Hello
I'm working with a PowerShellScript to generate an export of all approved Patches for a specifed wsus group.
The code sequence about the scope is as fallow:
$updateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope; $updateScope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::LatestRevisionApproved; #LatestRevisionApproved; $updateScope.UpdateSources = [Microsoft.UpdateServices.Administration.UpdateSources]::MicrosoftUpdate; $updateScope.UpdateApprovalActions = [Microsoft.UpdateServices.Administration.UpdateApprovalActions]::Install;
Now I saw that every update with [not approved] is in this scope, although it isn't approved.
The updates with [not approved (inherited)] are correct, meaning there aren't in the export file. (see printscreens in the end)
Why is this scope differnet?
Did anyone have an idea to solve this problem?
I'm working with an windows server 2012 R2 en
wsus version is 6.3.9600.16384
Here is the script:
################################################################################################ ########## Functions function menu { $date1 = [DateTime]::UtcNow.ToShortDateString() | % { $_.split("/")[0] } $date2 = [DateTime]::UtcNow.ToShortDateString() | % { $_.split("/")[1] } $date3 = [DateTime]::UtcNow.ToShortDateString() | % { $_.split("/")[2] } $date4 = (get-date -displayhint time).tostring() $date5 = $date4 | % { $_.split(" ")[1] } $date6 = $date5 | % { $_.split(":")[0] } $date7 = $date5 | % { $_.split(":")[1] } $datestamp = $date1+""+$date2+"-"+$date3+"-"+$date6+""+$date7; cls write-host "-------------------------------------------------------------" write-host "-------------------------------------------------------------" write-host "-------------------------------------------------------------" write-host "welcome to the WSUS approval system on" $datestamp write-host "Please select an option" write-host "" write-host " 1. Display WSUS patch summary" write-host " 2. Output text file and report of unapproved patches" write-host " 3. Output text file of approved patches for selected group" write-host " 4. Select Target Group" write-host " 11. Output text file of all approved patches" write-host " 5. Select Patch approval file" write-host " 6. Email Patch approval Report" write-host " 7. Apply Selected patch file to target group" write-host " 8. Clear selections" write-host " 9. View log of recent approvals" write-host " 10. Exit" write-host "" write-host "-------------------------------------------------------------" write-host "Selcted group: $selectedgroup" write-host "Selcted file: $selectedfile" #write-host "Target Group: " $targetgroup.name write-host "-------------------------------------------------------------" $elect = read-host "Please make a selection" switch ($elect) { 1 {patchsummary $wsus} 2 {unapprovedreport $DirectoryR} 3 {approvedreport $DirectoryR} 4 {groupselect} 5 {fileselect $Directory} 6 {emailreport} 7 {approvepatches} 8 {clearselect} 9 {viewlog} 10 {exit} 11 {approvedreportall $DirectoryR} default {"Sorry $elect is not a valid selection"; sleep 4; $elect = read-host "Do you wish to continue y/n"; escape $elect} } } function patchsummary ($wsus) { cls $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer(); $wsus.GetStatus() $elect = read-host "Do you wish to continue y/n"; escape $elect sleep 2 menu } function unapprovedreport { cls write-host "creating filess please wait" $updateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope; $updateScope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::NotApproved; $updateScope.UpdateSources = [Microsoft.UpdateServices.Administration.UpdateSources]::MicrosoftUpdate; $updateScope.UpdateApprovalActions = [Microsoft.UpdateServices.Administration.UpdateApprovalActions]::All; $title = "Unapproved-" $title2 = "ForResourceApproval" $approvedlist = $DirectoryR+""+$title+""+$Selectedgroup+"-"+$datestamp+".txt" $approvedlist2 = $DirectoryR+""+$title2+""+$Selectedgroup+"-"+$datestamp+".csv" $theupdates = $wsus.GetUpdates($updateScope); $theupdates | foreach-object { $update = $_ echo $update.Title | out-file $approvedlist -append } $theupdates = $wsus.GetUpdates($updateScope); $theupdates | foreach-object { $update = $_ $titles = $update.Title $desc = $update.Description $kbno = $update.KnowledgebaseArticles $bulno = $update.SecurityBulletins echo "$kbno@$bulno@$titles@$desc" | out-file $approvedlist2 -append } cls write-host "" write-host "Two files have been created in $DirectoryR" write-host "The file that can be used as the upload file is" write-host $approvedlist write-host "" write-host "" write-host "The @ delimited report CSV file is" write-host $approvedlist2 write-host "" write-host "" $elect = read-host "Do you wish to continue y/n" escape $elect write-host "" menu } function approvedreport { cls Write-Host "creating files please wait" $list = $wsus.GetComputerTargetGroups() for ($count=0; $count -lt $list.count; $count++) { $selgroup = $list.Item($count) if ($selgroup.Name -match $group) { $ApprovedGr = $list.Item($count) } } $updateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope; $updateScope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::LatestRevisionApproved; #LatestRevisionApproved; $updateScope.UpdateSources = [Microsoft.UpdateServices.Administration.UpdateSources]::MicrosoftUpdate; $updateScope.UpdateApprovalActions = [Microsoft.UpdateServices.Administration.UpdateApprovalActions]::Install; $title = "Approvals-" $approvedlist = $DirectoryR+""+$title+""+$Selectedgroup+"-"+$datestamp+".txt" $theupdates = $wsus.GetUpdates($updateScope); $theupdates | ForEach-Object { $update = $_ if ($update.GetUpdateApprovals($ApprovedGr).Count -ne 0) { $record = $update.Title #$update.Title+";"+$update.KnowledgebaseArticles+";"+$update.AdditionalInformationUrls echo $record | Out-File $approvedlist -append } } cls Write-Host "" Write-Host "The list of approved updates can be used as an upload file" Write-Host $approvedlist Write-Host "" Write-Host "" $elect = read-host "Do you wish to continue y/n" escape $elect Write-Host "" menu } function approvedreportall { cls Write-Host "creating files please wait" $updateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope; $updateScope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::LatestRevisionApproved; #LatestRevisionApproved; $updateScope.UpdateSources = [Microsoft.UpdateServices.Administration.UpdateSources]::MicrosoftUpdate; $updateScope.UpdateApprovalActions = [Microsoft.UpdateServices.Administration.UpdateApprovalActions]::all; $title = "Approvals-" $approvedlist = $DirectoryR+""+$title+""+$Selectedgroup+"-"+$datestamp+".txt" $theupdates = $wsus.GetUpdates($updateScope); $theupdates | ForEach-Object { $update = $_ echo $update.Title | Out-File $approvedlist -append } cls Write-Host "" Write-Host "The list of approved updates can be used as an upload file" Write-Host $approvedlist Write-Host "" Write-Host "" $elect = read-host "Do you wish to continue y/n" escape $elect Write-Host "" menu } function groupselect { Write-Host "Please select a target group number" sleep 1 $thelist $selection = read-host "Please select a target group number" sleep 2 write-host "You have selected group $selection" groupcheck $selection } function groupcheck ($selection, $all) { $all = $wsus.getcomputertargetgroups() $grouplist = $all | foreach-object {$_.name} $counter = 0 $thelist = $grouplist | foreach { $group = $_ $counter++"$delim$counter$delim$group" } $nogroups = $thelist.count cls write-host "selection is $selection" Write-Host "No Groups is $nogroups" if ($selection -gt $nogroups){ write-host "this is not a valid selection please re-run selecting a valid group"; sleep 6; menu} $select = "$delim$selection$delim" $selectedgroup = $thelist | where { $_ -match $select} $selectedgroup2 = $selectedgroup | % { $_.split("_")[2]} $selectedgroup = $selectedgroup2 $group = $selectedgroup sleep 3 targetgroup $all $selectedgroup } function targetgroup ($all, $selectedgroup) { $targetgroup = $all | where { $_.name -match $selectedgroup } childcheck $targetgroup } function childcheck ($targetgroup) { $targetgroup.GetChildTargetGroups() $childgroups = $targetgroup.GetChildTargetGroups() $childgroupcount = $childgroups.count if ($childgroupcount -gt 0){ Write-Host "The selected group has $childgroupcount sub folders patches applied at this level will apply to all sub folders" $elect = read-host "Do you wish to continue y/n" escape $elect} Write-Host "group has $childgroupcount sub folders" sleep 3 menu } function escape ($elect) { switch ($elect) { y {"the selection was $elect"} n {"the selection was $elect the script will now exit"; exit} default {"Sorry $elect is not a valid selection"; sleep 4; $elect = read-host "Do you wish to continue y/n"; escape $elect} } } function fileselect ($Directory) { write-host "Please select a file" sleep 1 $counter = 0 $delim = "_" $thefilelist = ls $Directory | foreach { $filename = $_ $counter++"$delim$counter$delim$filename" } $thefilelist $selection = read-host "Please select a target approval file" $select = "$delim$selection$delim" if ($selection -gt $counter){ write-host "this is not a valid selection please re-run selecting a valid file"; sleep 6; menu} sleep 2 $selectedfile2 = $thefilelist | where { $_ -match $select} | % { $_.split("_")[2]} $selectedfile = $Directory+""+$selectedfile2 sleep 2 menu } function emailreport { cls write-host "Please select a report file" sleep 1 $counter = 0 $delim = "_" $thefilelist = ls $DirectoryR "ForResourceApproval*"| foreach { $filename = $_ $counter++"$counter$delim$filename" } $thefilelist $selection = read-host "Please select a target report file" $select = $selection+"_" sleep 2 $selectedfile2 = $thefilelist | where { $_ -match $select} | % { $_.split("_")[1]} $selectedfiler = $DirectoryR+""+$selectedfile2 $smtpServer = "" $msg = new-object Net.Mail.MailMessage $att = new-object Net.Mail.Attachment($selectedfiler) $smtp = new-object Net.Mail.SmtpClient($smtpServer) $msg.From = "" $msg.To.Add("") $msg.Subject = "WSUS Report File" $msg.Body = "Report File Attached" $msg.Attachments.Add($att) $smtp.Send($msg) $att.Dispose() sleep 2 menu } function approvepatches { cls write-host "You have selected to apply patches listed in $selectedfile" write-host "to the selected group $selectedgroup" $thefile = cat $selectedfile $filesummary = $thefile.count write-host "Number of patches in file : $filesummary" $elect = read-host "Are you 100% happy you wish to continue y/n" cls $action = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::Install; $allupdates = $wsus.GetUpdates() $selection = cat $selectedfile $allupdates | foreach { $update = $_ $selection | foreach { $patchname = $_ $patchcheck = "$patchname" $updatecheck = $update.Title #$patchmatch = $allupdates | where { $_ -match $patchname} if ($updatecheck -contains $patchcheck){$patchmatch = $update write-host "--------------------------------Yes" $patchmatch.Title $patchmatch.Approve($action,$targetgroup) } } } logging menu } function clearselect { $selectedgroup = "" $selectedfile = "" $targetgroup = "" menu } function viewlog { cls $directoryl = "C:\wsus\wsus-operations\Log\" write-host "Please select a file" sleep 1 $counter = 0 $delim = "_" $thefilelist = ls $Directoryl | foreach { $filename = $_ $counter++"$counter$delim$filename" } $thefilelist $selection = read-host "Please select a target file" $select = $selection+"_" sleep 2 $selectedfile2 = $thefilelist | where { $_ -match $select} | % { $_.split("_")[1]} $selectedfilel = $directoryl+""+$selectedfile2 write-host "Log file" cat $selectedfilel $elect = read-host "Do you wish to continue y/n"; escape $elect sleep 2 menu } function logging { $who = [System.Security.Principal.WindowsIdentity]::GetCurrent() $whoisit = $who.Name $groupis = $targetgroup.name $emailFrom = "" $emailTo = "" $subject = "WSUS Install log" $body = "$whoisit has applied $filesummary patches to $groupis" $body2 = $datestamp+"-"+$body echo $body2 | out-file "C:\wsus\wsus-operations\Log\activitylog.txt" -append $smtpServer = "" $smtp = new-object Net.Mail.SmtpClient($smtpServer) $smtp.Send($emailFrom, $emailTo, $subject, $body) } ################################################################################################################################### ######### Main Script for WSUS patch approval ##################################################################################### [reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer(); $updateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope; $updateScope.UpdateSources = [Microsoft.UpdateServices.Administration.UpdateSources]::MicrosoftUpdate; $updateScope.UpdateApprovalActions = [Microsoft.UpdateServices.Administration.UpdateApprovalActions]::All; $all = $wsus.getcomputertargetgroups() $grouplist = $all | foreach-object {$_.name} $date1 = [DateTime]::UtcNow.ToShortDateString() | % { $_.split("/")[0] } $date2 = [DateTime]::UtcNow.ToShortDateString() | % { $_.split("/")[1] } $date3 = [DateTime]::UtcNow.ToShortDateString() | % { $_.split("/")[2] } $date4 = (get-date -displayhint time).tostring() $date5 = $date4 | % { $_.split(" ")[1] } $date6 = $date5 | % { $_.split(":")[0] } $date7 = $date5 | % { $_.split(":")[1] } $datestamp = $date1+""+$date2+"-"+$date3+"-"+$date6+""+$date7; $counter = 0 $delim = "_" $thelist = $grouplist | foreach { $group = $_ $counter++"$delim$counter$delim$group" } $Directory = "C:\wsus\wsus-operations\Upload\" $DirectoryR = "C:\wsus\wsus-operations\Report\" $selectedgroup = "" $selectedfile = "" write-host "-------------------------------------------------------------" write-host "-------------------------------------------------------------" write-host "----------------WSUS PATCH OPERATIONS------------------------" menu $selectedgroup