Share via


Approve Updates By Computer Groupt

Question

Thursday, July 10, 2014 11:52 AM

I've found this script to ApproveUpdatesByComputerGroupt and it works, my problem is now, I only need to approve Classification  'Critical Updates' 'Security Updates' 'Updates', because I will not approve service packs for OS / SQL, etc. 

I'm using SCCM, but Failover Cluster should I use WSUS.

But no matter what I've tried, I can not really get it to work, so .. 

Help Help

# ApproveUpdatesByComputerGroup.ps1
 
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
 
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer()
 
$ComputerTargetGroups = $wsus.GetComputerTargetGroups()
Write-Host "Warning: This will approve all NotApproved updates for a Computer Group" -ForegroundColor Red
Write-Host "Computer Groups"
$Count = 0
foreach ($ComputerTargetGroup in $ComputerTargetGroups) {
    Write-Host $Count - $ComputerTargetGroup.Name
    $Count++
}
$ComputerGroupToUpdate = Read-Host "Select Computer Group to update. [0 - $($Count-1)]"
Write-Host "Finding all updates needing approval and approving them"
 
$ComputerGroupName = $ComputerTargetGroups[$ComputerGroupToUpdate].Name
$ComputerGroupId = $ComputerTargetGroups[$ComputerGroupToUpdate].Id
 
$ComputersToScan = $wsus.GetComputerTargetGroup($ComputerGroupId).GetComputerTargets()
foreach ($ComputerToScan in $ComputersToScan) {
 
    $ComputerTargetToUpdate = $wsus.GetComputerTargetByName($ComputerToScan.FullDomainName)
    # Get all Not Installed updates available to the computer
    $NeededAndNotInstalled = $ComputerTargetToUpdate.GetUpdateInstallationInfoPerUpdate() | where {
                                                                                                    ($_.UpdateInstallationState -eq "NotInstalled") `
                                                                                                    -and ($_.UpdateApprovalAction -eq "NotApproved")}
    foreach ($UpdateToApprove in $NeededAndNotInstalled)
    {
        Approve-WsusUpdate -Action Install -TargetGroupName $ComputerGroupName -Update $(Get-WsusUpdate -UpdateId $UpdateToApprove.UpdateId) -Verbose
    }
 
}
Write-Host "Done approving updates"
sleep -Seconds 5

All replies (6)

Thursday, July 10, 2014 8:28 PM ✅Answered

Something like this should work; just adjust the first two variables to match your environment. I think there may be a better way to do it, but it is just not coming to me at this time.

$WSUSServer = 'SERVERNAME'
$Group = 'CLUSTER_SERVERS'
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($WSUSServer,$False)
$ComputerTargetGroups = $wsus.GetComputerTargetGroups()

$UpdateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$UpdateScope.ApprovedStates = 'NotApproved'
$UpdateScope.IncludedInstallationStates = 'NotInstalled'

##Classifications
#Get all Classifications for specific Classifications
$updateClassifications = $wsus.GetUpdateClassifications() | Where {
  $_.Title -Match "Critical Updates|Updates|Security Updates"
}
$UpdateScope.Classifications.AddRange($updateClassifications)

$ComputerScope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$TargetGroup = $ComputerTargetGroups | Where {$_.Name -eq $Group}
[void]$computerscope.ComputerTargetGroups.Add($TargetGroup)

$Clients = $WSUS.GetComputerTargets($computerscope)
$Updates = $Clients.GetUpdateInstallationInfoPerUpdate($UpdateScope) | Select -Unique -ExpandProperty UpdateID
ForEach ($Item in $Updates) {    
    $Update = $wsus.GetUpdate($Item)
    Write-Verbose "Install $($Update.title) on $($TargetGroup.name)" -Verbose
    $Update.Approve('Install',$TargetGroup)
}

Boe Prox
Blog | Twitter
PoshWSUS | PoshPAIG | PoshChat | PoshEventUI
PowerShell Deep Dives Book


Thursday, July 10, 2014 11:54 AM

I have ask i WSUS forum, the say try Powershell forum...

http://social.technet.microsoft.com/Forums/windowsserver/en-US/68522326-6b46-4e5a-9918-f4cb519bff27/help-powershell-and-wsus-approve-updates-by-computer-group?forum=winserverwsus


Monday, July 14, 2014 5:05 AM

Hi Søren Møller DK,

I’m writing to just check in to see if the suggestions were helpful. If you need further help, please feel free to reply this post directly so we will be notified to follow it up.

                              

If you have any feedback on our support, please click here.

Best Regards,

Anna Wang

TechNet Community Support


Thursday, August 7, 2014 8:22 AM

I have been on holiday, and back not, will test...

/Søren


Thursday, August 7, 2014 8:56 AM

Can´t get it to work.. This is the error

Exception calling "GetUpdateServer" with "2" argument(s): "The request failed with HTTP status 404: Not Found.
At E:\update.ps1:4 char:1

  • $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($W ...

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : WebException

You cannot call a method on a null-valued expression.
At E:\update.ps1:5 char:1

  • $ComputerTargetGroups = $wsus.GetComputerTargetGroups()

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At E:\update.ps1:13 char:1

  • $updateClassifications = $wsus.GetUpdateClassifications() | Where {

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Exception calling "AddRange" with "1" argument(s): "Value cannot be null.
Parameter name: value"
At E:\update.ps1:16 char:1

  • $UpdateScope.Classifications.AddRange($updateClassifications)

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

Exception calling "Add" with "1" argument(s): "Value cannot be null.
Parameter name: value"
At E:\update.ps1:20 char:1

  • [void]$computerscope.ComputerTargetGroups.Add($TargetGroup)

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

You cannot call a method on a null-valued expression.
At E:\update.ps1:22 char:1

  • $Clients = $WSUS.GetComputerTargets($computerscope)

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At E:\update.ps1:23 char:1

  • $Updates = $Clients.GetUpdateInstallationInfoPerUpdate($UpdateScope) | Select -U ...

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

And the WSUS is running.

PS E:\ Get-WsusServer | Select *

WebServiceUrl                    : http://SC-CM01:8530/ApiRemoting30/WebService.asmx
BypassApiRemoting                : False
IsServerLocal                    : True
Name                             : SC-CM01
Version                          : 6.2.9200.16384
IsConnectionSecureForApiRemoting : True
PortNumber                       : 8530
PreferredCulture                 : da
ServerName                       : SC-CM01
UseSecureConnection              : False
ServerProtocolVersion            : 1.8


Thursday, August 7, 2014 10:43 AM | 1 vote

It works now.... 

$WSUSServer = 'xxxxxxxxxxxxxxxx'

$Group = 'CLUSTER_Test'
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($WSUSServer,$False,"8530")
$ComputerTargetGroups = $wsus.GetComputerTargetGroups()

$UpdateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$UpdateScope.ApprovedStates = 'NotApproved'
$UpdateScope.IncludedInstallationStates = 'NotInstalled'

##Classifications
#Get all Classifications for specific Classifications
$updateClassifications = $wsus.GetUpdateClassifications() | Where {
  $_.Title -Match "Critical Updates|Updates|Security Updates"
}
$UpdateScope.Classifications.AddRange($updateClassifications)

$ComputerScope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$TargetGroup = $ComputerTargetGroups | Where {$_.Name -eq $Group}
[void]$computerscope.ComputerTargetGroups.Add($TargetGroup)

$Clients = $WSUS.GetComputerTargets($computerscope)
$Updates = $Clients.GetUpdateInstallationInfoPerUpdate($UpdateScope) | Select -Unique -ExpandProperty UpdateID
ForEach ($Item in $Updates) {    
    $Update = $wsus.GetUpdate($Item)
    Write-Verbose "Install $($Update.title) on $($TargetGroup.name)" -Verbose
    $Update.Approve('Install',$TargetGroup)
}

Boe Prox 1000 thanks for the help