Install Windows Updates and Hotfixes from Command Line

Scenario:  You have a lot of Windows Updates and Hotfixes that you need to install manually.  You want to do the following:

  1. Script the install
  2. Do not restart the server after the update is installed — (so you can manually restart it when you are ready)

Scriptlets:

Download the updates to a folder and copy that folder to the servers requiring the update.

#Collect your Servers into a variable
$Servers = Get-exchangeserver ex*

#Create an folder to copy your updates to
$Servers.name | %{ MD \$_c$updatesCluster_Updates }

#Copy your updates to that new folder
$servers.name | %{ Copy-item "C:Cluster_updates*.msu" "\$_c$updatesCluster_updates"

Install the updates on each server by running the following command from an elevated command prompt:

FOR %h IN (*.msu) DO START /WAIT WUSA %h /QUIET /NORESTART

To verify the updates are installed on each one of your servers, run the following PowerShell commandlet:

$servers.name | %{ get-hotfix -computername $_ | Where InstalledOn -gt 2/5/2017}

 

 

 

PowerShell: Copy and rename file for to keep as a backup

Scenario:  You want to use PowerShell to make a backup of a specific file across many servers and store it locally.  We will perform this on a Web.Config file for IIS. The file once copied will be stored as C:SharebkupWebsvr1-wwwroot_web.config.

 

Script:

#Collect your Servers into a variable
$servers = "WebSvr1","WebSvr2","WebSvr3"

#Copy the file from the remote server to a local share

$Servers | %{
Copy-Item -Path "\$_c$inetpubwwwrootweb.config" -Destination "C:Sharebkup$_-wwwroot_web.config" 
}

Powershell: Increase the max size limit for ActiveSync Properties/Metadata in you Web.Config

Scenario:  You need to increase the ActiveSync default message size limit from 10MB to a larger value.  By default the RequestFilteringLimit set in IIS is 30,000,000 bytes (approx. 28MB) so we will operate within the limitations of that setting, meaning you cannot go higher than 28MB unless you set that property to a higher value.  So lets be safe and set that value to 15MB on all multirole exchange 2013 servers.  We need to edit the web.config files in the following directories:
Client Access: 

%ExchangeInstallPath%FrontEndHttpProxySyncweb.config – maxRequestLength=”10240″ kilobytes

Mailbox

%ExchangeInstallPath%ClientAccessSyncweb.config – maxRequestLength=”10240″ kilobytes

%ExchangeInstallPath%ClientAccessSyncweb.config  – <add key=”MaxDocumentDataSize” value=”10240000″>  bytes
Script:  IISReset is not needed!

#variables
$servers = (Get-ExchangeServer).name
$MRL = "15360"  #15MB in KB
$MDDS = "15728640" #15MB in Bytes


$Servers | %{
#ClientAccess
    #MaxRequestLength
    $webConfig = "\$_c$Program FilesMicrosoftExchange ServerV15FrontEndHttpProxysyncweb.config" 
    $doc = new-object System.Xml.XmlDocument 
    $doc.Load($webConfig) 
    $doc.get_DocumentElement()."system.web".httpruntime.maxrequestlength = $MRL 
    #Save Document
    $doc.Save($webConfig) 

#Mailbox
    #MaxRequestLength
    $webConfig = "\$_c$Program FilesMicrosoftExchange ServerV15ClientAccessSyncweb.config" 
    $doc = new-object System.Xml.XmlDocument 
    $doc.Load($webConfig) 
    $doc.get_DocumentElement()."system.web".httpruntime.maxrequestlength = $MRL 
    #MaxDocumentDataSize
    $key = "MaxDocumentDataSize"
    $node = $doc.SelectSingleNode('configuration/appSettings/add[@key="' + $key + '"]') 
    $node.Attributes['value'].Value = $MDDS 
    #Save Document
    $doc.Save($webConfig) 
}

 

 

Perform an NSLookup in PowerShell to find the IP Address(es) tied to a hostname

Scenario:  You want to perform an NSLookup in PowerShell so you can use the multiple IP addresses that you are using for DNS Round Robin in another PowerShell Query.

Solution: Run the following:

#Collect the IP Addresses of the hostname into a variable
$address = [system.net.dns]::GetHostAddresses("mail.domain.com" | Select IPAddressToString)

#For Each Loop it with a command
$address | Select -expandproperty IPAddressToString | %{ Get-ADComputer $_ }

 

Error “A reboot from a previous installation is pending” during Exchange InstallUninstall

Scenario:  When attempting to install/uninstall Exchange, you receive the following error during readiness checks:

“A reboot from a previous installation is pending”

Even after a reboot, it doesn’t clear this error.

Solution:

  1. Clear values out of the PendingFileRenameOperations key located at: HKLMSYSTEMCurrentControlSetControlSessionManagerPendingFileRenameOperations
  2. You may need to clear out the content of this key as well located at: HKLMSystemControlSet001ControlSessionManager

Determine which Windows Management Framework is installed in PowerShell

Scenario: You want to easily detect which Windows Management Framework is installed on your server.

Solution:

Run either in Powershell

host  | Select Version

OR

$PSVersionTable.PSVersion 

 

Determine TTL on a DNS record

Scenario:  You changed an IP address on a DNS record and you want to determine the TTL (Time to Live) value of the DNS record to figure out when this DNS record will become refreshed.

Solution: Run the following NSLookup command with the -type=soa record against the DNS name you wish to determine TTL.

nslookup -type=soa http://www.google.com

 

Use PowerShell to filter by or count when files were created.

Scenario:  You suspect that logs are not being generated properly and you want to find the logs or count the logs based on any log created after a specific date.

#View the file information for the logs:
Get-ChildItem "\Ex2013Server1C$Program FilesMicrosoftExchange ServerV15LoggingHttpProxyEas" | Where-Object { $_.CreationTime -gt [datetime]"2016/05/17" } | Sort-Object CreationTime | Format-Table Name, CreationTime

#Count the Logs
(Get-ChildItem "\Ex2013Server1C$Program FilesMicrosoftExchange ServerV15LoggingHttpProxyEas" | Where-Object { $_.CreationTime -gt [datetime]"2016/05/17" } | Sort-Object CreationTime | Format-Table Name, CreationTime).count

Monitor Registry Key via Powershell for Remote Computers (Monitor SSLv3)

Scenario:  You have a registry key you want to monitor and to alert you if the value changes.  We noticed after the install of Exchange 2013 CU11, it enabled SSLv3 which was manually disabled before.

Script:

#Start
#Define Server Collection
$Servers = Get-ExchangeServer | Where AdminDisplayVersion -like "Version 15*" 

#Loop for SSLv3
$sslv3_svr = @()   #Create Array Variable
$Servers | %{
              $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $_.name)
              $RegKey= $Reg.OpenSubKey("SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server")
              $SSLv3 = $RegKey.GetValue("Enabled")
              If($SSLV3 -ne 0){
                     $sslv3_svr += $_.name
              }
            }
#Email it
$body =""
$smtp = "smtp.domain.com"
[string[]]$to = "steve@domain.com","Batman@domain.com"
$from = "SSLv3Monitor@Domain.com"
$subject = "SSLv3 monitor" 
$body += "<b><Font color=#0404B4>SSLv3 is enabled on the following server and needs to be turned off: </b></font><br><br>"
$body += "<Font color=red>$sslv3_svr</font><br><br><br>" 
send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -Body $body -BodyAsHtml -Priority high

Schedule a Task via Powershell on remote systems

Scenario:  You want to schedule a task remotely via Powershell on remote systems:

Script:

$Servers = "Win2012Svr1", "Win2012Svr2","Win2012Svr3"

$Servers |%{
Invoke-Command {
$action = New-ScheduledTaskAction -Execute 'C:TaskClientStatsClientStats.bat'

$trigger =  New-ScheduledTaskTrigger -Daily -At 1am

Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "ClientStats" -Description "Daily Stat Dump" -user "domainadmin" -password "adminpassword1" -runlevel Highest
} -ComputerName $_

}