Advertisement
syntax53

WSUS Automation.ps1

Nov 6th, 2017
1,478
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ###
  2. # Created by Matt Snead -- syntax53@gmail.com / http://www.twistedtek.net
  3. #
  4. # Ran with no switches on the local WSUS server (with mail server information entered below, and with matching group names),
  5. # this script will decline the specified updates, then approve specified updates, then do a cleanup (same as doing it from
  6. # the WSUS GUI).  After that it will email lists of computers with failed updates and a list of updates that have been
  7. # failing to install.  It will also email whenever new updates and classifications are found within 31 days.
  8. #
  9. # If you use Windows Defender you would want to comment out the 'DeclineUpdates -title "Windows Defender"'
  10. # and then UNcomment 'ApproveUpdates -class "Definition Updates" -group_name "All Computers" -action $approve_install -days_old 0'
  11. #
  12. # NOTE: INHERITANCE ASSUMED TO BE ENABLED FROM TOP > DOWN
  13. #
  14. # You can specify your smtp server, from/to addresses, WSUS groups, etc as switches, or specify them all below in the Param's section.
  15. #
  16. # Sample Usage: powershell.exe -ExecutionPolicy Unrestricted -nologo -NoProfile -File "D:\WSUS Scripts\WSUS Automation.ps1"
  17. #
  18. # Optional switches:
  19. # -UseSSL 0 or 1    : Defaults to No (0) -- SSL connection to WSUS server
  20. # -trialrun 0 or 1  : Defaults to No (0) -- 1 means no changes will be made.  Simulate a regular run and send emails on what WOULD be done.
  21. # -emaillog 0 or 1  : Defaults to Yes (1) -- Send or Don't send emails.
  22. # -printlog 0 or 1  : Defaults to Yes (1) -- Print or don't print a lot of the results to console
  23. #
  24. # -skip_decline, -skip_approve, -skip_cleanup, -skip_lists  : Skip various sections of the script (usually for testing only to speed things up)
  25. ##
  26.  
  27. Param(
  28.     [string]$WsusServer = ([system.net.dns]::GetHostByName('localhost')).hostname,
  29.     [int]$PortNumber = 8530,
  30.     [int]$UseSSL = 0,
  31.    
  32.     [string]$SMTPServer = "smtp_server.domain.name.com",
  33.     [string]$From = "wsus@domain.name.com",
  34.     [string]$To = "notifyuser@domain.name.com",
  35.     [string]$Subject = "WSUS Automation",
  36.    
  37.     [string]$LIMBO_group = "Unassigned Computers",
  38.     [string]$ASSIGNED_group = "Assigned",
  39.     [string]$NORMAL_group = "Normal",
  40.     [string]$FAST_DEPLOY_group = "Fast Deploy",
  41.     [string]$SERVERS_group = "Servers",
  42.  
  43.     [int]$TrialRun = 0,
  44.     [int]$EmailLog = 1,
  45.     [int]$PrintLog = 1,
  46.    
  47.     [int]$important_update_days = 15,
  48.     [int]$regular_update_days = 28,
  49.    
  50.     [int]$skip_decline = 0,
  51.     [int]$skip_approve = 0,
  52.     [int]$skip_cleanup = 0,
  53.     [int]$skip_lists = 0
  54. )
  55.  
  56. $TrialRun = [System.Convert]::ToBoolean($TrialRun)
  57. $EmailLog = [System.Convert]::ToBoolean($EmailLog)
  58. $PrintLog = [System.Convert]::ToBoolean($PrintLog)
  59. $UseSSL = [System.Convert]::ToBoolean($UseSSL)
  60.  
  61. $skip_decline = [System.Convert]::ToBoolean($skip_decline)
  62. $skip_approve = [System.Convert]::ToBoolean($skip_approve)
  63. $skip_cleanup = [System.Convert]::ToBoolean($skip_cleanup)
  64. $skip_lists = [System.Convert]::ToBoolean($skip_lists)
  65.  
  66. $Style = "<Style>BODY{font-size:12px;font-family:verdana,sans-serif;color:navy;font-weight:normal;}" + `
  67.             "TABLE{border-width:1px;cellpadding=10;border-style:solid;border-color:navy;border-collapse:collapse;}" + `
  68.             "TH{font-size:12px;border-width:1px;padding:10px;border-style:solid;border-color:navy;}" + `
  69.             "TD{font-size:10px;border-width:1px;padding:10px;border-style:solid;border-color:navy;}</Style>"
  70.  
  71. $Table = @{Name="Date";Expression={[string]$($_.CreationDate).ToShortDateString()}},`
  72.     @{Name="Title";Expression={[string]$_.Title}},`
  73.     @{Name="KB Article";Expression={[string]$_.KnowledgebaseArticles}},`
  74.     @{Name="Classification";Expression={[string]$_.UpdateClassificationTitle}},`
  75.     @{Name="Product Title";Expression={[string]$_.ProductTitles}},`
  76.     @{Name="Product Family";Expression={[string]$_.ProductFamilyTitles}}
  77.  
  78. $Table_Updates = @{Name="Date";Expression={[string]$($_.CreationDate).ToShortDateString()}},`
  79.     @{Name="UpdateTitle";Expression={[string]$_.UpdateTitle}},`
  80.     @{Name="Needed";Expression={[string]$_.NeededCount}},`
  81.     @{Name="Installed";Expression={[string]$_.InstalledCount}},`
  82.     @{Name="Failed";Expression={[string]$_.FailedCount}}
  83.  
  84. $Table_Computers = @{Name="Computer";Expression={[string]$_.ComputerTarget}},`
  85.     @{Name="Needed";Expression={[string]$_.NeededCount}},`
  86.     @{Name="Failed";Expression={[string]$_.FailedCount}},`
  87.     @{Name="Last";Expression={[string]$($_.LastReported).ToShortDateString()}}
  88.    
  89. $Table_Print = @{Name="Title";Expression={[string]$_.Title}},`
  90.     @{Name="Classification";Expression={[string]$_.UpdateClassificationTitle}}
  91.  
  92. Write-Host ""
  93. If ($TrialRun) {
  94.     Write-Host "Trial Run: YES"
  95.     $Subject += " Trial Run"
  96. } else {
  97.     Write-Host "Trial Run: NO"
  98. }
  99. Write-Host ""
  100.  
  101. Function SendEmailStatus($From, $To, $Subject, $SMTPServer, $BodyAsHtml, $Body) {
  102.     $SMTPMessage = New-Object System.Net.Mail.MailMessage $From, $To, $Subject, $Body
  103.     $SMTPMessage.IsBodyHTML = $BodyAsHtml
  104.     $SMTPClient = New-Object System.Net.Mail.SMTPClient $SMTPServer
  105.     $SMTPClient.Send($SMTPMessage)
  106.     If($? -eq $False){Write-Warning "$($Error[0].Exception.Message) | $($Error[0].Exception.GetBaseException().Message)"}
  107.     $SMTPMessage.Dispose()
  108.     rv SMTPClient
  109.     rv SMTPMessage
  110. }
  111.  
  112. Write-Host "Connecting to WSUS..."
  113. Write-Host ""
  114.  
  115. #Connect to the WSUS interface.
  116. [reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null
  117.  
  118. #Define the actions available for approving a patch
  119. $approve_all = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::All
  120. $approve_install = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::Install
  121. $approve_NotApproved = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::NotApproved
  122. $approve_Uninstall = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::Uninstall
  123.  
  124. $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($WsusServer,$UseSSL,$PortNumber);
  125. If ($? -eq $False) {
  126.     Write-Warning "Something went wrong connecting to the WSUS interface on $WsusServer server: $($Error[0].Exception.Message)"
  127.    
  128.     If ($EmailLog) {
  129.         $Body = ConvertTo-Html -head $Style -Body "Something went wrong connecting to the WSUS interface on $WsusServer server: $($Error[0].Exception.Message)" | Out-String
  130.         $Body = $Body.Replace("<table>`r`n</table>", "")
  131.         SendEmailStatus -From $From -To $To -Subject "$Subject - ERROR" -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  132.     }
  133.     Exit
  134. }
  135.  
  136. Function DeclineUpdates($title, $match_and) {
  137.     if ($match_and) {
  138.         Write-Host "Searching for '$title' && '$match_and' ..."
  139.     } else {
  140.         Write-Host "Searching for '$title' ..."
  141.     }
  142.     Write-Host ""
  143.    
  144.     $email_subject = "$Subject - Declined Updates :: $title"
  145.     if ($match_and) { $email_subject += " $match_and" }
  146.    
  147.     $updateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope;
  148.     $updateScope.ApprovedStates = "Any"
  149.     $updateScope.TextIncludes = $title
  150.    
  151.     if ($match_and) {
  152.         $MatchedUpdates = $wsus.GetUpdates($updateScope) | ?{-not $_.IsDeclined -and $_.Title -match $title -and $_.Title -match $match_and}
  153.     } else {
  154.         $MatchedUpdates = $wsus.GetUpdates($updateScope) | ?{-not $_.IsDeclined -and $_.Title -match $title}
  155.     }
  156.    
  157.     If($MatchedUpdates) {
  158.    
  159.         If ($TrialRun -eq $False) { $MatchedUpdates | %{$_.Decline()} }
  160.        
  161.         If ($EmailLog) {
  162.             $email_subject += " (" + $MatchedUpdates.Count + ")"
  163.             $Body = $MatchedUpdates | Select $Table | ConvertTo-HTML -head $Style
  164.             SendEmailStatus -From $From -To $To -Subject $email_subject -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  165.         }
  166.  
  167.         If ($PrintLog) {
  168.             $MatchedUpdates | Select $Table_Print | Format-List
  169.         }
  170.    
  171.     } Else {
  172.         Write-Host "No Matches."
  173.         Write-Host ""
  174.     }
  175. }
  176.  
  177.  
  178. Function GetListOfApprovedUpdates_WithInheritance($class, $group_name) {
  179.     $list = New-Object System.Collections.ArrayList
  180.    
  181.     $group = $wsus.GetComputerTargetGroups() | ? {$_.Name -eq $group_name}
  182.     If ([string]::IsNullOrEmpty($group)) { return $list }
  183.    
  184.     $classifications=$wsus.GetUpdateClassifications() | ?{$_.Title -eq $class}
  185.     if ([string]::IsNullOrEmpty($classifications)) { return $list }
  186.    
  187.     $ApprovedUpdatesScope = new-object Microsoft.UpdateServices.Administration.UpdateScope
  188.     $ApprovedUpdatesScope.ApprovedStates = "Any"
  189.     $ApprovedUpdatesScope.Classifications.AddRange($classifications)
  190.     $ret = $ApprovedUpdatesScope.ApprovedComputerTargetGroups.Add($group)
  191.     $PrevApprovedUpdates = $wsus.GetUpdateApprovals($ApprovedUpdatesScope)
  192.    
  193.     foreach ($approval in $PrevApprovedUpdates) {
  194.         $ret = $list.Add($wsus.GetUpdate($approval.UpdateID).ID.UpdateID)
  195.     }
  196.    
  197.     Try {
  198.         $parent = $group.GetParentTargetGroup().name
  199.         if ($parent) {
  200.             $list += GetListOfApprovedUpdates_WithInheritance -class $class -group_name $parent
  201.         }
  202.     } Catch {}
  203.    
  204.     return $list
  205. }
  206.  
  207. Function ApproveUpdates($class, $group_name, $action, $days_old = 0, $title = "", $exclude_text = "", $exclude_title = "") {
  208.     $days_old = [int]$days_old
  209.     $email_subject = "$Subject - Approved $class / $group_name"
  210.     if ($title -ne "") { $email_subject += " - $title" }
  211.    
  212.     Write-Host "Searching for computer group '$group_name' ..."
  213.    
  214.     $group = $wsus.GetComputerTargetGroups() | ? {$_.Name -eq $group_name}
  215.     If ([string]::IsNullOrEmpty($group)) {
  216.         Write-Host "Computer group '$group_name' not found!"
  217.         Write-Host ""
  218.        
  219.         If ($EmailLog) {
  220.             $email_subject += " (ERROR)"
  221.             $Body = ConvertTo-Html -head $Style -Body "Computer group '$group_name' not found!" | Out-String
  222.             $Body = $Body.Replace("<table>`r`n</table>", "")
  223.             SendEmailStatus -From $From -To $To -Subject "$Subject - ERROR" -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  224.         }
  225.        
  226.         Return
  227.     }
  228.    
  229.     Write-Host "Searching for $class ..."
  230.    
  231.     $classifications=$wsus.GetUpdateClassifications() | ?{$_.Title -eq $class}
  232.     if ([string]::IsNullOrEmpty($classifications)) {
  233.         Write-Host "Classification '$class' not found!"
  234.         Write-Host ""
  235.        
  236.         If ($EmailLog) {
  237.             $email_subject += " (ERROR)"
  238.             $Body = ConvertTo-Html -head $Style -Body "Classification '$class' not found!" | Out-String
  239.             $Body = $Body.Replace("<table>`r`n</table>", "")
  240.             SendEmailStatus -From $From -To $To -Subject "$Subject - ERROR" -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  241.         }
  242.        
  243.         Return
  244.     }
  245.    
  246.     Write-Host ""
  247.    
  248.     $approved_col = GetListOfApprovedUpdates_WithInheritance -class $class -group_name $group_name
  249.     #$approved_col
  250.     #$approved_col | Export-Csv  "d:\approved_updates.csv" -NoTypeInformation -Encoding UTF8 -Delimiter ','
  251.    
  252.     $FilterUpdateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope;
  253.     $FilterUpdateScope.ApprovedStates = "Any"
  254.     $FilterUpdateScope.ToCreationDate = (Get-Date).AddDays(-$days_old)
  255.     $ret = $FilterUpdateScope.Classifications.AddRange($classifications)
  256.    
  257.     if ($title) { $FilterUpdateScope.TextIncludes = $title }
  258.     if ($exclude_text) { $FilterUpdateScope.TextNotIncludes = $exclude_text }
  259.    
  260.     $MatchedUpdates = $wsus.GetUpdates($FilterUpdateScope) | ?{-not $_.IsDeclined }
  261.     if ($title) { $MatchedUpdates = $MatchedUpdates | ?{$_.Title -match $title} }
  262.     if ($exclude_title) { $MatchedUpdates = $MatchedUpdates | ?{$_.Title -notmatch $exclude_title} }
  263.    
  264.     #$MatchedUpdates | Select $Table | Export-Csv  "d:\matched_updates.csv" -NoTypeInformation -Encoding UTF8 -Delimiter ','
  265.     If($MatchedUpdates) {
  266.        
  267.         $UpdatesCollection = New-Object Microsoft.UpdateServices.Administration.UpdateCollection
  268.        
  269.         Foreach ($update in $MatchedUpdates) {
  270.             if ($approved_col -notcontains $update.ID.UpdateID) {
  271.                 If ($TrialRun -eq $False) {
  272.                     if ( -not $update.EulaAccepted ) { $ret = $update.AcceptEula() }
  273.                     if ( $update.RequiresLicenseAgreementAcceptance ) {
  274.                         $eula = $update.GetLicenseAgreement()
  275.                         $ret = $update.AcceptLicenseAgreement()
  276.                     }
  277.                    
  278.                     $ret = $update.Approve($action,$group)
  279.                 }
  280.                
  281.                 $ret = $UpdatesCollection.Add($update)
  282.             }
  283.         }
  284.        
  285.         if ($UpdatesCollection.Count -gt 0) {
  286.             If ($EmailLog) {
  287.                 $email_subject += " (" + $UpdatesCollection.Count + ")"
  288.                 $Body = $UpdatesCollection | Select $Table | ConvertTo-HTML -head $Style
  289.                 SendEmailStatus -From $From -To $To -Subject $email_subject -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  290.             }
  291.  
  292.             If ($PrintLog) {
  293.                 $UpdatesCollection | Select $Table_Print | Format-List
  294.                 Write-Host "Total:" $UpdatesCollection.Count
  295.                 Write-Host ""
  296.             }
  297.         } else {
  298.             Write-Host "No Updates to Approve."
  299.             Write-Host ""
  300.         }
  301.     } Else {
  302.         Write-Host "No Matches."
  303.         Write-Host ""
  304.     }
  305. }
  306.  
  307. Function DoCleanup() {
  308.     Write-Host "Executing Cleanup..."
  309.    
  310.     $CleanupScopeObject = New-Object Microsoft.UpdateServices.Administration.CleanupScope
  311.     $CleanupScopeObject.CleanupObsoleteComputers = $True
  312.     $CleanupScopeObject.CleanupObsoleteUpdates = $True
  313.     $CleanupScopeObject.CleanupUnneededContentFiles = $True
  314.     $CleanupScopeObject.CompressUpdates = $True
  315.     $CleanupScopeObject.DeclineExpiredUpdates = $True
  316.     $CleanupScopeObject.DeclineSupersededUpdates = $True
  317.  
  318.     $CleanupTASK = $wsus.GetCleanupManager()
  319.  
  320.     $Results = $CleanupTASK.PerformCleanup($CleanupScopeObject)
  321.    
  322.     $changes = $Results.SupersededUpdatesDeclined + $Results.ExpiredUpdatesDeclined + $Results.ObsoleteUpdatesDeleted + $Results.UpdatesCompressed + $Results.ObsoleteComputersDeleted + $Results.DiskSpaceFreed
  323.    
  324.     if ($changes) {
  325.         $DObject = New-Object PSObject
  326.         $DObject | Add-Member -MemberType NoteProperty -Name "Superseded Declined" -Value $Results.SupersededUpdatesDeclined
  327.         $DObject | Add-Member -MemberType NoteProperty -Name "Expired Declined" -Value $Results.ExpiredUpdatesDeclined
  328.         $DObject | Add-Member -MemberType NoteProperty -Name "Updates Deleted" -Value $Results.ObsoleteUpdatesDeleted
  329.         $DObject | Add-Member -MemberType NoteProperty -Name "Revisions Deleted" -Value $Results.UpdatesCompressed
  330.         $DObject | Add-Member -MemberType NoteProperty -Name "Computers Deleted" -Value $Results.ObsoleteComputersDeleted
  331.         $DObject | Add-Member -MemberType NoteProperty -Name "Disk Space Freed" -Value $Results.DiskSpaceFreed.ToString('N0')
  332.        
  333.         If ($EmailLog) {
  334.             $Body = $DObject | ConvertTo-Html -Head $Style
  335.             SendEmailStatus -From $From -To $To -Subject "$Subject - Cleanup Report" -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  336.         }
  337.         If ($PrintLog) {
  338.             $DObject | Format-Table
  339.         }
  340.     } else {
  341.         Write-Host "Nothing to clean."
  342.         Write-Host ""
  343.     }
  344. }
  345.  
  346. Function ListFailedComputers($days_old = 5) {
  347.     $computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
  348.     $computerscope.FromLastReportedStatusTime = (Get-Date).AddDays(-$days_old)
  349.    
  350.     $updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
  351.     $updatescope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::Failed
  352.     $updatescope.ApprovedStates = "Any"
  353.     $updatescope.FromArrivalDate = (Get-Date).AddDays(-730)
  354.    
  355.     $fails = $wsus.GetSummariesPerComputerTarget($updatescope,$computerscope)
  356.     if ($fails.Count -lt 1) { Return }
  357.    
  358.     $FailedComputers = New-Object Microsoft.UpdateServices.Administration.UpdateSummaryCollection
  359.    
  360.     foreach ($fail in $fails) {
  361.         if (($fail.DownloadedCount + $fail.NotInstalledCount) -gt 0 -and $fail.FailedCount -gt 0) {
  362.             $ret = $FailedComputers.Add($fail)
  363.             #$fail | Format-Table
  364.         }
  365.     }
  366.    
  367.     if ($FailedComputers.Count -lt 1) { Return }
  368.    
  369.     $result = $FailedComputers | Select @{L='ComputerTarget';E={($wsus.GetComputerTarget([guid]$_.ComputerTargetId)).FullDomainName}},@{L='LastReported';E={($wsus.GetComputerTarget([guid]$_.ComputerTargetId)).LastReportedStatusTime}},@{L='NeededCount';E={($_.DownloadedCount + $_.NotInstalledCount)}},FailedCount | Sort-Object FailedCount -descending | Select $Table_Computers
  370.     If ($EmailLog) {
  371.         $Body = $result | ConvertTo-Html -Head $Style
  372.         SendEmailStatus -From $From -To $To -Subject ("$Subject - Failed Computers (" + $FailedComputers.Count + ")") -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  373.     }
  374.     If ($PrintLog) {
  375.         $result
  376.     }
  377. }
  378.  
  379. Function ListFailedUpdates() {
  380.     $updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
  381.     $computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
  382.    
  383.     $updatescope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::Failed
  384.     $updatescope.ApprovedStates = "Any"
  385.     $updatescope.FromArrivalDate = (Get-Date).AddDays(-730)
  386.  
  387.     $fails = $wsus.GetSummariesPerUpdate($updatescope,$computerscope)
  388.     if ($fails.Count -lt 1) { Return }
  389.    
  390.     $FailedUpdates = New-Object Microsoft.UpdateServices.Administration.UpdateSummaryCollection
  391.    
  392.     foreach ($fail in $fails) {
  393.         #if (($fail.DownloadedCount + $fail.NotInstalledCount) -gt 4 -and $fail.FailedCount -gt (($fail.DownloadedCount + $fail.NotInstalledCount)/2) -and $fail.FailedCount -ge $fail.InstalledCount) {
  394.         if (($fail.DownloadedCount + $fail.NotInstalledCount) -gt 4 -and $fail.FailedCount -gt (($fail.DownloadedCount + $fail.NotInstalledCount)/2)) {
  395.             $update = $wsus.GetUpdate([guid]$fail.UpdateId)
  396.             if ($update) {
  397.                 if ($update.IsDeclined -eq $False -and $update.IsApproved -eq $True) {
  398.                     $ret = $FailedUpdates.Add($fail)
  399.                     #$fail | Format-Table
  400.                 }
  401.             }
  402.         }
  403.     }
  404.    
  405.     if ($FailedUpdates.Count -lt 1) { Return }
  406.    
  407.     $result = $FailedUpdates  | Select @{L='UpdateTitle';E={($wsus.GetUpdate([guid]$_.UpdateId)).Title}}, @{L='CreationDate';E={($wsus.GetUpdate([guid]$_.UpdateId)).CreationDate}}, @{L='NeededCount';E={($_.DownloadedCount + $_.NotInstalledCount)}},InstalledCount,FailedCount | Sort-Object FailedCount -descending | Select $Table_Updates
  408.     If ($EmailLog) {
  409.         $Body = $result | ConvertTo-Html -Head $Style
  410.         SendEmailStatus -From $From -To $To -Subject ("$Subject - Failed Updates (" + $FailedUpdates.Count + ")") -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  411.     }
  412.     If ($PrintLog) {
  413.         $result
  414.     }
  415. }
  416.  
  417. Function GetNewProductsClassifications() {
  418.     $days_back = 31
  419.     $new_products = $wsus.GetUpdateCategories((Get-Date).AddDays(-$days_back),(Get-Date)) | select Title, Description, arrivaldate
  420.     $new_classifications = $wsus.GetUpdateClassifications((Get-Date).AddDays(-$days_back),(Get-Date)) | select Title, Description, arrivaldate
  421.    
  422.     if ($new_products.count -gt 0 -or $new_classifications.count -gt 0) {
  423.         If ($EmailLog) {
  424.             $latest_date = Get-Date -Year 2000 -Month 1 -Day 1
  425.            
  426.             foreach ($obj in $new_products) {
  427.                 if ($obj.ArrivalDate -gt $latest_date) { $latest_date = $obj.ArrivalDate }
  428.             }
  429.            
  430.             foreach ($obj in $new_classifications) {
  431.                 if ($obj.ArrivalDate -gt $latest_date) { $latest_date = $obj.ArrivalDate }
  432.             }
  433.             $email_subject = "$Subject - New Products / Classifications (" + $latest_date.ToString("MM/dd/yyyy") + ")"
  434.            
  435.             $Body = ""
  436.             $nohead = 0
  437.             if ([string]::IsNullOrEmpty($new_classifications) -eq $false) {
  438.                 $Body += "<strong>New Classifications:</strong><br><br>" + ($new_classifications | ConvertTo-Html -Head $Style) + "<br><br>"
  439.                 $nohead = 1
  440.             }
  441.             if ([string]::IsNullOrEmpty($new_products) -eq $false) {
  442.                 if ($nohead) {
  443.                     $Body += "<strong>New Products:</strong><br><br>" + ($new_products | ConvertTo-Html) + "<br><br>"
  444.                 } else {
  445.                     $Body += "<strong>New Products:</strong><br><br>" + ($new_products | ConvertTo-Html -Head $Style) + "<br><br>"
  446.                 }
  447.             }
  448.            
  449.             SendEmailStatus -From $From -To $To -Subject $email_subject -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
  450.         }
  451.         If ($PrintLog) {
  452.             if ([string]::IsNullOrEmpty($new_products) -eq $false) { $new_products | Format-List }
  453.             if ([string]::IsNullOrEmpty($new_classifications) -eq $false) { $new_classifications | Format-List }
  454.         }
  455.     } else {
  456.         If ($PrintLog) {
  457.             Write-Host "No new products or classifications."
  458.             Write-Host ""
  459.         }
  460.     }
  461. }
  462.  
  463. if (-not $skip_decline) {
  464.     DeclineUpdates -title "Microsoft Office" -match_and "64-Bit"
  465.     DeclineUpdates -title "Microsoft Word" -match_and "64-Bit"
  466.     DeclineUpdates -title "Microsoft Excel" -match_and "64-Bit"
  467.     DeclineUpdates -title "Microsoft PowerPoint" -match_and "64-Bit"
  468.     DeclineUpdates -title "Microsoft Access" -match_and "64-Bit"
  469.     DeclineUpdates -title "Microsoft Publisher" -match_and "64-Bit"
  470.     DeclineUpdates -title "Microsoft Project" -match_and "64-Bit"
  471.     DeclineUpdates -title "Microsoft Outlook" -match_and "64-Bit"
  472.     DeclineUpdates -title "Microsoft OneNote"
  473.     DeclineUpdates -title "Microsoft InfoPath"
  474.     DeclineUpdates -title "Microsoft Lync"
  475.     DeclineUpdates -title "ia64"
  476.     DeclineUpdates -title "itanium"
  477.     DeclineUpdates -title "Windows 10 Insider"
  478.     DeclineUpdates -title " beta"
  479.     DeclineUpdates -title "Multilingual User Interface"
  480.     DeclineUpdates -title "Lang Pack"
  481.     DeclineUpdates -title "Language Packs"
  482.     DeclineUpdates -title "LanguageFeature"
  483.     DeclineUpdates -title "Language Interface Pack"
  484.     DeclineUpdates -title "Web Apps Server"
  485.     DeclineUpdates -title "SharePoint"
  486.     DeclineUpdates -title "Microsoft Business"
  487.     DeclineUpdates -title "Skype for Business"
  488.     DeclineUpdates -title "OneDrive for Business"
  489.     DeclineUpdates -title "Preview of"
  490.     DeclineUpdates -title "Windows Defender"
  491. }
  492.  
  493. if (-not $skip_approve) {
  494.     #ApproveUpdates -class "Definition Updates" -group_name "All Computers" -action $approve_install -days_old 0
  495.  
  496.     ApproveUpdates -class "Security Updates" -group_name "All Computers" -action $approve_install -days_old 0 -title "Flash Player"
  497.     ApproveUpdates -class "Critical Updates" -group_name "All Computers" -action $approve_install -days_old 0 -title "Flash Player"
  498.     ApproveUpdates -class "Updates" -group_name "All Computers" -action $approve_install -days_old 0 -title "Flash Player"
  499.  
  500.     ApproveUpdates -class "Security Updates" -group_name $FAST_DEPLOY_group -action $approve_install -days_old 0
  501.     ApproveUpdates -class "Security Updates" -group_name $ASSIGNED_group -action $approve_install -days_old $important_update_days -exclude_text "Security Monthly Quality Rollup" -exclude_title "Preview of"
  502.     ApproveUpdates -class "Security Updates" -group_name $LIMBO_group -action $approve_install -days_old $important_update_days -exclude_text "Security Monthly Quality Rollup" -exclude_title "Preview of"
  503.  
  504.     ApproveUpdates -class "Critical Updates" -group_name $FAST_DEPLOY_group -action $approve_install -days_old 0
  505.     ApproveUpdates -class "Critical Updates" -group_name $NORMAL_group -action $approve_install -days_old $important_update_days
  506.     ApproveUpdates -class "Critical Updates" -group_name $LIMBO_group -action $approve_install -days_old $important_update_days
  507.     ApproveUpdates -class "Critical Updates" -group_name $SERVERS_group -action $approve_install -days_old $regular_update_days
  508.  
  509.     ApproveUpdates -class "Updates" -group_name $FAST_DEPLOY_group -action $approve_install -days_old 0
  510.     ApproveUpdates -class "Updates" -group_name $NORMAL_group -action $approve_install -days_old $regular_update_days -exclude_title "Preview of"
  511.     ApproveUpdates -class "Updates" -group_name $LIMBO_group -action $approve_install -days_old $regular_update_days -exclude_title "Preview of"
  512.     ApproveUpdates -class "Updates" -group_name $SERVERS_group -action $approve_install -days_old ($regular_update_days * 2) -exclude_title "Preview of"
  513.  
  514.     ApproveUpdates -class "Update Rollups" -group_name $FAST_DEPLOY_group -action $approve_install -days_old 0
  515.     ApproveUpdates -class "Update Rollups" -group_name $NORMAL_group -action $approve_install -days_old $regular_update_days
  516.     ApproveUpdates -class "Update Rollups" -group_name $LIMBO_group -action $approve_install -days_old $regular_update_days
  517.     ApproveUpdates -class "Update Rollups" -group_name $SERVERS_group -action $approve_install -days_old ($regular_update_days * 2)
  518.  
  519.     ApproveUpdates -class "Service Packs" -group_name $FAST_DEPLOY_group -action $approve_install -days_old 0
  520.     ApproveUpdates -class "Service Packs" -group_name $NORMAL_group -action $approve_install -days_old $regular_update_days
  521.     ApproveUpdates -class "Service Packs" -group_name $LIMBO_group -action $approve_install -days_old $regular_update_days
  522.     ApproveUpdates -class "Service Packs" -group_name $SERVERS_group -action $approve_install -days_old ($regular_update_days * 2)
  523. }
  524.  
  525. If ($TrialRun -eq $False -and -not $skip_cleanup) { DoCleanup }
  526.  
  527. if (-not $skip_lists) {
  528.     ListFailedUpdates
  529.     ListFailedComputers
  530.     GetNewProductsClassifications
  531. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement