This Exchange management shell command will reach out to all your hub transport servers and then search through the tracking logs for messages greater than a given size. Handy if you want to track down larger messages moving through your Exchange environment. This particular example searches for stuff greater than 50MB.
Get-ExchangeServer | where {$_.isHubTransportServer -eq $true} | Get-MessageTrackingLog -resultsize unlimited -start "8/1/2010 12:00AM" -end "8/4/2010 11:59pm" | where {$_.TotalBytes -gt 50000000}
Wednesday, August 4, 2010
Thursday, April 8, 2010
Powershell script to find a specific OS in a domain
Here's a piece of code modified from this scripting guy post that allows you to list computer accounts with specific operating systems that aren't disabled in your domain. It's written as a function so you just have to write your query string and pass it to the function. aka GetDomainComps *2008* will return all the AD computer accounts with 2008 in their name.
Function GetDomainComps
{param ($strOS)
$strCategory = "computer"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = "(&(objectCategory=$strCategory)(operatingSystem=$strOS)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
$colProplist = "name"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults)
{$objComputer = $objResult.Properties; $objComputer.name}
}
GetDomainComps *2003*
Function GetDomainComps
{param ($strOS)
$strCategory = "computer"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = "(&(objectCategory=$strCategory)(operatingSystem=$strOS)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
$colProplist = "name"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults)
{$objComputer = $objResult.Properties; $objComputer.name}
}
GetDomainComps *2003*
Monday, March 15, 2010
Setup Netapp System Manager Read-Only and Cifs Admins
I had a need to create a read-only account to access our netapp filers from Netapp System Manager but also wanted to have an account that had read-only to everything but read and write to cifs configuration.
Luckily creating a read-only account is clearly detailed in TR-3358 so I just had to add on the cifs read-write portion for my purposes. The following are the commands that I used. Note the pieces that I added to the info in TR-3358 were the role for cifs read/write adn the api-cf-status for an active/active filer.
useradmin role add nsm-login -a login-http-admin,api-system-get-*
useradmin role add nsm-view –a api-aggr-list-info,api-disk-sanown-list-info,api-license-list-info,api-options-get,api-perf-object-get-instances,api-snmp-status,api-volume-list-info*,cli-priv,api-aggr-options-list-info,api-aggr-check-spare-low,api-cf-status
useradmin role add nsm-volumes-view -a api-volume-get-root-name,api-snapshot-reserve-list-info,api-volume-get-language,api-volume-options-list-info,cli-date
useradmin role add nsm-sharedfolders-view -a api-cifs-share-list-iter*,api-nfs-exportfs-list-rules,api-cifs-session-list-iter*
useradmin role add nsm-qtree-view -a api-qtree-list-iter*
useradmin role add nsm-disk-view -a api-system-cli,api-disk-list-info,cli-options
useradmin role add nsm-aggr-view -a api-aggr-get-root-name,api-snapshot-list-info
useradmin role add nsm-sharedfolders-write -a cli-cifs,api-cifs*
**********************
useradmin group add nsm-storage-view-cifswrite -r nsm-login,nsm-view,nsm-volumes-view,nsm-sharedfolders-view,nsm-qtree-view,nsm-disk-view,nsm-aggr-view,nsm-sharedfolders-write
useradmin group add nsm-storage-view -r nsm-login,nsm-view,nsm-volumes-view,nsm-sharedfolders-view,nsm-qtree-view,nsm-disk-view,nsm-aggr-view
*********************
useradmin user add nsmcifsmgr -g nsm-storage-view,nsm-storage-view-cifswrite
useradmin user add nsmviewonly -g nsm-storage-view
Luckily creating a read-only account is clearly detailed in TR-3358 so I just had to add on the cifs read-write portion for my purposes. The following are the commands that I used. Note the pieces that I added to the info in TR-3358 were the role for cifs read/write adn the api-cf-status for an active/active filer.
useradmin role add nsm-login -a login-http-admin,api-system-get-*
useradmin role add nsm-view –a api-aggr-list-info,api-disk-sanown-list-info,api-license-list-info,api-options-get,api-perf-object-get-instances,api-snmp-status,api-volume-list-info*,cli-priv,api-aggr-options-list-info,api-aggr-check-spare-low,api-cf-status
useradmin role add nsm-volumes-view -a api-volume-get-root-name,api-snapshot-reserve-list-info,api-volume-get-language,api-volume-options-list-info,cli-date
useradmin role add nsm-sharedfolders-view -a api-cifs-share-list-iter*,api-nfs-exportfs-list-rules,api-cifs-session-list-iter*
useradmin role add nsm-qtree-view -a api-qtree-list-iter*
useradmin role add nsm-disk-view -a api-system-cli,api-disk-list-info,cli-options
useradmin role add nsm-aggr-view -a api-aggr-get-root-name,api-snapshot-list-info
useradmin role add nsm-sharedfolders-write -a cli-cifs,api-cifs*
**********************
useradmin group add nsm-storage-view-cifswrite -r nsm-login,nsm-view,nsm-volumes-view,nsm-sharedfolders-view,nsm-qtree-view,nsm-disk-view,nsm-aggr-view,nsm-sharedfolders-write
useradmin group add nsm-storage-view -r nsm-login,nsm-view,nsm-volumes-view,nsm-sharedfolders-view,nsm-qtree-view,nsm-disk-view,nsm-aggr-view
*********************
useradmin user add nsmcifsmgr -g nsm-storage-view,nsm-storage-view-cifswrite
useradmin user add nsmviewonly -g nsm-storage-view
Tuesday, February 9, 2010
Expiring Users Script That Sends an Email
Below is a script that I created to query AD for expiring user accounts and then to email the results out. The only flaw is that it doesn't filter account that have already expired, so those will show. Which yeah I could add that in but it would be MUCH easier to just re-write this in powershell to do the same.
As always test and use at your own risk.
' VB Script to scrape AD for users with expiring dates
' set and to email the results in an html table with info
StrEmailTo = "address@here.com; address2@here.com"
StrEmailFrom = "fromaddress@here.com"
StrEmailSubject = "insert subject here"
Strsmtpserver = "youremailserver.domain.com"
Dim lngDate, objDate, dtmAcctExp, k
' Obtain local time zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLMSystemCurrentControlSetControl" _
& "TimeZoneInformationActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
lngBias = 0
For k = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(k) * 256^k)
Next
End If
' Use ADO to search the domain.
Set adoConnection = CreateObject("ADODB.Connection")
Set adoCommand = CreateObject("ADODB.Command")
adoConnection.Provider = "ADsDSOOBject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
' Determine the DNS domain from the RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
' Filter to retrieve all user objects with accounts
' that expire.
strFilter = "(&(objectCategory=person)(objectClass=user)" _
& "(!accountExpires=0)(!accountExpires=9223372036854775807))"
strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter _
& ";distinguishedName,accountExpires;subtree"
' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute
Set objMessage = CreateObject("CDO.Message")
objMessage.Subject = StrEmailSubject
objMessage.From = StrEmailFrom
objMessage.To = StrEmailTo
objMessage.HTMLBody = "<font size=" & chr(34) & "2" & chr(34) & " face=" & chr(34) & "Arial" & chr(34) & ">" & _
"Below is the expiring users report:<br><br><table border-" & Chr(34) & "1" & Chr(34) & "><tr><th>Date Expires</th><th>-----</th><th>User</th></tr><tr>"
'**********************
' Enumerate the recordset.
Do Until adoRecordset.EOF
' Retrieve attribute values.
strDN = adoRecordset.Fields("distinguishedName").Value
lngDate = adoRecordset.Fields("accountExpires")
' Convert accountExpires to date in current time zone.
Set objDate = lngDate
dtmAcctExp = Integer8Date(objDate, lngBias)
' Output to console.
objMessage.HTMLBody = objMessage.HTMLBody & "<tr><td>" & dtmAcctExp & " " & "</td><td> </td><td>" & strDN & "</td></tr>"
adoRecordset.MoveNext
Loop
adoRecordset.Close
objMessage.HTMLBody = objMessage.HTMLBody & "</table>"
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = Strsmtpserver
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objMessage.Configuration.Fields.Update
objMessage.Send
'**********************
' Clean up.
adoConnection.Close
Function Integer8Date(ByVal objDate, ByVal lngBias)
' Function to convert Integer8 (64-bit) value to a date, adjusted for
' local time zone bias.
Dim lngAdjust, lngDate, lngHigh, lngLow
lngAdjust = lngBias
lngHigh = objDate.HighPart
lngLow = objdate.LowPart
' Account for bug in IADslargeInteger property methods.
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0) Then
lngAdjust = 0
End If
lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow) / 600000000 - lngAdjust) / 1440
Integer8Date = CDate(lngDate)
End Function
As always test and use at your own risk.
' VB Script to scrape AD for users with expiring dates
' set and to email the results in an html table with info
StrEmailTo = "address@here.com; address2@here.com"
StrEmailFrom = "fromaddress@here.com"
StrEmailSubject = "insert subject here"
Strsmtpserver = "youremailserver.domain.com"
Dim lngDate, objDate, dtmAcctExp, k
' Obtain local time zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLMSystemCurrentControlSetControl" _
& "TimeZoneInformationActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
lngBias = 0
For k = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(k) * 256^k)
Next
End If
' Use ADO to search the domain.
Set adoConnection = CreateObject("ADODB.Connection")
Set adoCommand = CreateObject("ADODB.Command")
adoConnection.Provider = "ADsDSOOBject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
' Determine the DNS domain from the RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
' Filter to retrieve all user objects with accounts
' that expire.
strFilter = "(&(objectCategory=person)(objectClass=user)" _
& "(!accountExpires=0)(!accountExpires=9223372036854775807))"
strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter _
& ";distinguishedName,accountExpires;subtree"
' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute
Set objMessage = CreateObject("CDO.Message")
objMessage.Subject = StrEmailSubject
objMessage.From = StrEmailFrom
objMessage.To = StrEmailTo
objMessage.HTMLBody = "<font size=" & chr(34) & "2" & chr(34) & " face=" & chr(34) & "Arial" & chr(34) & ">" & _
"Below is the expiring users report:<br><br><table border-" & Chr(34) & "1" & Chr(34) & "><tr><th>Date Expires</th><th>-----</th><th>User</th></tr><tr>"
'**********************
' Enumerate the recordset.
Do Until adoRecordset.EOF
' Retrieve attribute values.
strDN = adoRecordset.Fields("distinguishedName").Value
lngDate = adoRecordset.Fields("accountExpires")
' Convert accountExpires to date in current time zone.
Set objDate = lngDate
dtmAcctExp = Integer8Date(objDate, lngBias)
' Output to console.
objMessage.HTMLBody = objMessage.HTMLBody & "<tr><td>" & dtmAcctExp & " " & "</td><td> </td><td>" & strDN & "</td></tr>"
adoRecordset.MoveNext
Loop
adoRecordset.Close
objMessage.HTMLBody = objMessage.HTMLBody & "</table>"
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = Strsmtpserver
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objMessage.Configuration.Fields.Update
objMessage.Send
'**********************
' Clean up.
adoConnection.Close
Function Integer8Date(ByVal objDate, ByVal lngBias)
' Function to convert Integer8 (64-bit) value to a date, adjusted for
' local time zone bias.
Dim lngAdjust, lngDate, lngHigh, lngLow
lngAdjust = lngBias
lngHigh = objDate.HighPart
lngLow = objdate.LowPart
' Account for bug in IADslargeInteger property methods.
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0) Then
lngAdjust = 0
End If
lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow) / 600000000 - lngAdjust) / 1440
Integer8Date = CDate(lngDate)
End Function
Wednesday, December 16, 2009
Set Your McData/Brocade Spheron Fiber Switch Banner
Had to do this today on a Sphereon 4400 switch and it wasn't quite the simplest procedure so figured I'd jot it down.
-Enable SSH (configure->ssh)
-Then SSH to the switch and use the following commands to set the banner text:
config switch banner
bannerText 1 "================Banner============="
bannerText 2 "This system is restricted....."
bannerText 3 "authorized users..."
bannerText 19 "All users must comply with Company Policy and..."
bannerText 20 "Instructions regarding the protection of..."
bannerText 21 "===============End Banner=========="
Obviously your own banner text will go in there and will look a bit different. The numbers refer to the line number and the text following it must be included in quotes. You can show your current banner by typing the command show when you're in the banner config mode.
-Enable SSH (configure->ssh)
-Then SSH to the switch and use the following commands to set the banner text:
config switch banner
bannerText 1 "================Banner============="
bannerText 2 "This system is restricted....."
bannerText 3 "authorized users..."
bannerText 19 "All users must comply with Company Policy and..."
bannerText 20 "Instructions regarding the protection of..."
bannerText 21 "===============End Banner=========="
Obviously your own banner text will go in there and will look a bit different. The numbers refer to the line number and the text following it must be included in quotes. You can show your current banner by typing the command show when you're in the banner config mode.
Wednesday, November 25, 2009
Netapp and Backup Exec Compression Vs Deduplication
I recently did a small-scale test with our Netapp and Backup Exec 12.5 to determine if it would be best to compress or not compress backup data written to disk. (Either way the assumption was that the volume was to be deduplicated on the netapp post-process regardless of compression setting.)
Note: Backup Exec handles the compression on the application level and the netapp handles the deduplication on the hardware/storage level.
I ran across this page which did a similar test however didn't much pursue multiple copies of the same data, nor was backup exec used so I figured I'd do my own testing.
So the question is, which results in the lowest disk usage, compression and deduplication, or just deduplication?
The Test
-2 LUNs, each 250 GB
-One with compression and the other without
-Both LUNs deduplicated after all backups were run
Each LUN had written to it:
-3 backups of the same oracle server
-2 backups of the same sharepoint server
-2 backups of domain controller 1
-2 backups of domain controller 2
Both DCs (1 and 2) were 2008 and thus quite similar so there should be a fair amount of commonality among the data.
Results
Windows usage:
with compress - 117 GB
no compress - 170 GB
output from the NetApp 'df -sh' command:
Filesystem used saved %saved
/vol/compress/ 186GB 63GB 25%
/vol/nocompress/ 162GB 88GB 35%
Conclusions
Overall this seems to suggest that it would be better to leave compression off in backup exec if you're backing up to a netapp disk.
Though for these results to be a little more conclusive I would probably have to have included more iterations of backups to the volumes.
This was interesting as our production backup to disk volume of compressed data is usually around 30% savings, which suggests that the same volume might be around 40% savings or more if it wasn't compressed.
The NetApp disk volumes in my test were also presented as LUNs rather than CIFS shares, which may have adversely affected deduplication percentages.
Application of Results
Hopefully this is helpful for anyone in the same boat using netapp storage and backup exec. Unfortunately to be able to turn off compression it has to be done on a per-job basis in backup exec (not per disk target). In my environment I use a disk pool containing netapp and local storage so I would have to target specific volumes for jobs to be able to get the higher storage efficiency using these results. Which for a 10% increase that probably won't be worth doing.
Note: Backup Exec handles the compression on the application level and the netapp handles the deduplication on the hardware/storage level.
I ran across this page which did a similar test however didn't much pursue multiple copies of the same data, nor was backup exec used so I figured I'd do my own testing.
So the question is, which results in the lowest disk usage, compression and deduplication, or just deduplication?
The Test
-2 LUNs, each 250 GB
-One with compression and the other without
-Both LUNs deduplicated after all backups were run
Each LUN had written to it:
-3 backups of the same oracle server
-2 backups of the same sharepoint server
-2 backups of domain controller 1
-2 backups of domain controller 2
Both DCs (1 and 2) were 2008 and thus quite similar so there should be a fair amount of commonality among the data.
Results
Windows usage:
with compress - 117 GB
no compress - 170 GB
output from the NetApp 'df -sh' command:
Filesystem used saved %saved
/vol/compress/ 186GB 63GB 25%
/vol/nocompress/ 162GB 88GB 35%
Conclusions
Overall this seems to suggest that it would be better to leave compression off in backup exec if you're backing up to a netapp disk.
Though for these results to be a little more conclusive I would probably have to have included more iterations of backups to the volumes.
This was interesting as our production backup to disk volume of compressed data is usually around 30% savings, which suggests that the same volume might be around 40% savings or more if it wasn't compressed.
The NetApp disk volumes in my test were also presented as LUNs rather than CIFS shares, which may have adversely affected deduplication percentages.
Application of Results
Hopefully this is helpful for anyone in the same boat using netapp storage and backup exec. Unfortunately to be able to turn off compression it has to be done on a per-job basis in backup exec (not per disk target). In my environment I use a disk pool containing netapp and local storage so I would have to target specific volumes for jobs to be able to get the higher storage efficiency using these results. Which for a 10% increase that probably won't be worth doing.
Friday, August 7, 2009
Powershell script for prepending and appending text
I recently had the need to go through a text file and prepend a string to every line, and while that's ok for a couple of lines it doesn't work for a file with hundreds and thousands of lines. So here's the powershell command to do that:
get-content file.txt | foreach-object {add-content output.txt "text_to_add $_"}
This goes through every line in file.txt, adds "text_to_add" followed by a space and then whatever was on the original line (which is put in by the $_ ) and then writes that out to output.txt.
If you wanted to append to the end of every line it would be:
get-content file.txt | foreach-object {add-content output.txt "$_ text_to_add "}
If you wanted search for and replace only specific lines you'd write a function to do so which a good example of searching through a text file I've found here.
Subscribe to:
Posts (Atom)