locked
Approve a list of KB updates in a CSV file for a specific group in WSUS By using PowerShell. RRS feed

  • Question

  • Dears,

    could you help my with script to approve a list of KB updates in a CSV file for a specific group in WSUS By using PowerShell

    Group name: SERVER2008-R2-SP1 Deployment

    File path: C:\temp\Update.csv

    Regards.

    Monday, July 4, 2016 10:02 PM

Answers

  • Your script seems to have a lot of issues.  You should avoid using single letters for variables.  Things like $a, $isavup, and $u mean nothing to the person reading this.  Be more descriptive so it's easier to share your script. You should avoid using Write-Host whenever possible.  Google it and read why.  The script seems way more complicated than it needs to be.  Personally I'd download and use the PoshWSUS module for this.  You can get it here:

    http://poshwsus.codeplex.com/releases/view/118164

    Try something like what I have below.  Copy and save it to a .ps1 file.  Call it from powershell like this:

    & .\Approve-WSUSUpdatesFromFile.ps1 -WsusServer myserver -ApprovedUpdateFile ".\UpdatesToApprove.txt" -WSUSGroup "SERVER2008-R2-SP1 Deployment"


    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true,
                    Position=0)]
        $WsusServer,
        [int]
        $Port = "80",
        [Parameter(Mandatory=$true)]
        [ValidateScript({Test-Path $_ -PathType ‘Leaf’})] 
        [string]
        $ApprovedUpdateFile,
        [Parameter(Mandatory=$true)]
        [string]
        $WSUSGroup
    )
    
    Begin {
        Connect-PoshWSUSServer -WsusServer $WsusServer -port $Port
    }
    Process {
        if ($ApprovedUpdateFile) {
            Get-Content $ApprovedUpdateFile | Foreach {
                Get-PoshWSUSUpdate $_ | Approve-PoshWSUSUpdate -Action Install -Group $WSUSGroup –PassThru
            }
        }
        Else {
            Write-Warning "No Updates found to approve."
        }
    }
    End {
        Disconnect-PoshWSUSServer
    }



    • Edited by Brian Klish Thursday, July 7, 2016 2:29 AM forgot the $WSUSGroup param
    • Marked as answer by Yaqoop Hadadi Sunday, July 10, 2016 9:06 AM
    Thursday, July 7, 2016 2:27 AM
  • Actually my If statement is pointless since the parameter is mandatory.  Originally wrote it differently.  Also no point having the begin, process, or end blocks since I'm not accepting input from pipeline.  Originally I was going to so I wrote it that way.  This makes more sense:

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true,
                    Position=0)]
        [string]
        $WsusServer,
        [int]
        $Port = "80",
        [Parameter(Mandatory=$true)]
        [ValidateScript({Test-Path $_ -PathType ‘Leaf’})] 
        [string]
        $ApprovedUpdateFile,
        [Parameter(Mandatory=$true)]
        [string]
        $WSUSGroup
    )
    
    Connect-PoshWSUSServer -WsusServer $WsusServer -port $Port
    
    Get-Content $ApprovedUpdateFile | Foreach {
        Get-PoshWSUSUpdate $_ | Approve-PoshWSUSUpdate -Action Install -Group $WSUSGroup –PassThru
    }
    
    Disconnect-PoshWSUSServer


    • Marked as answer by Yaqoop Hadadi Sunday, July 10, 2016 9:06 AM
    Friday, July 8, 2016 12:50 PM

All replies

  • This is a concept that I've considered doing as well.  I don't agree with it, but some venders only test and approve updates periodically.  It's usually a few weeks after the updates are released which makes it very difficult to find the list of approved updates and then go install them.  Really need them to release the approved updates in a downloadable file that we could somehow import and script against.

    Do you have a starting point for your script?  Are you getting stuck on a certain part?

    Tuesday, July 5, 2016 6:04 PM
  • maybe this?

    https://gallery.technet.microsoft.com/scriptcenter/47de741b-b64a-4d8a-8bc1-53e6bf7f7792


    Don [doesn't work for MSFT, and they're probably glad about that ;]

    Tuesday, July 5, 2016 10:09 PM
  • Don, that's a neat script, but it doesn't accept a csv of approved updates.  It doesn't take input at all really so we can't modify it make it work either.  That script works off the unapproved updates on the WSUS server.  Won't really work for this unfortunately, but glad you pointed it out since it's actually a pretty cool script.
    Tuesday, July 5, 2016 10:52 PM
  • My apologies as I may have spoken too soon.  I was just reading the script a little deeper and it sounds like this might work.  I'm investigating further...
    Tuesday, July 5, 2016 11:13 PM
  • It appears that script will work, but I'm not a big fan of the way it works.  It can approve updates for the specified group by importing a text file - one update per line.  It does so by matching each line up with the title of all updates in WSUS.  There isn't any validation in the script though.  So what happens if you inadvertently put just a space on a line?  You just approved all updates since all updates contain a space.  If you're careful you could put the KB article ID one per line and I think that would work though.
    Wednesday, July 6, 2016 12:58 AM
  • In all fairness the script's author did not intend for someone to feed it a manually built file.  It's intended to be used with files it generates.
    Wednesday, July 6, 2016 4:10 AM
  • In your experience , do you know any tools or Software can do my questions ? 
    Wednesday, July 6, 2016 6:00 PM
  • I am trying to use this script but it use the id of KB can you help me to change it to the KB id :

    This script will help to read the list of update ID from a file and then approve them for a specific group

    #Change server name and port number and $True if it is on SSL
    [String]$updateServer1 = "servername
    [Boolean]$
    useSecureConnection = $False
    [Int32]$portNumber =80

    #Group to which you need to approve
    $groupname = "
    SERVER2008-R2-SP1 Deployment"
    #File where update if for the updates to be installed are saved
    $path = "
    C:\temp\Update.csv"

    # Load .NET assembly
    [void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")

    # Connect to WSUS Server
    $updateServer = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($updateServer1,$useSecureConnection,$portNumber)
    write-host "Connected sucessfully To WSUS server >>>…." -foregroundcolor "yellow"
    Import-csv -path $path -Header updateid | foreach `
    {
         $approveupdate =$approveupdate =$_.updateID
         $isavup= 'False'
         $u = $updateServer.GetUpdates()
         foreach ($u1 in $u )
        {
             $a=New-Object Microsoft.UpdateServices.Administration.UpdateRevisionId
             $a=$u1.id

            #checking if the update ID in question is to be approved if yes approve else loop through
                if ($a.UpdateId -eq $approveupdate)

                { 
                     $isavup= 'True'
                     $group = $updateServer.GetComputerTargetGroups() | where {$_.Name -eq $groupname}
                     $isapp=$u1.GetUpdateApprovals($group)
                     #Checking if already approved and if not approve it
                     if ($isapp.action -eq 'Install')
                     {
                     write-host "Update ID: " $a.UpdateId "For Group :" $groupname  "already approved" -foregroundcolor "yellow"
                     }
                     else
                     {                
                      write-host "Approving update " $a.UpdateId "For Group :" $groupname   -foregroundcolor "yellow"
                      $group = $updateServer.GetComputerTargetGroups() | where {$_.Name -eq $groupname}
                      $u1.Approve(“Install”,$group) | out-null
                      }
                }
        }
        if ($isavup -eq 'False')
        {
        write-host "Update ID" $approveupdate "Not in WSUS Database"   -foregroundcolor "yellow"
        }
    }

    #This will help to catch the exception if any and display

    trap
    {
    write-host "Error Occurred"
    write-host "Exception Message: "
    write-host $_.Exception.Message
    write-host $_.Exception.StackTrace
    exit
    }


    Wednesday, July 6, 2016 6:10 PM
  • I'm not sure what you're asking.  It sounds like you're saying the script accepts the KB, but you want to change it so it accepts the KB.  Makes no sense to me.  Sounds like the same thing.
    Wednesday, July 6, 2016 6:28 PM
  • Your script seems to have a lot of issues.  You should avoid using single letters for variables.  Things like $a, $isavup, and $u mean nothing to the person reading this.  Be more descriptive so it's easier to share your script. You should avoid using Write-Host whenever possible.  Google it and read why.  The script seems way more complicated than it needs to be.  Personally I'd download and use the PoshWSUS module for this.  You can get it here:

    http://poshwsus.codeplex.com/releases/view/118164

    Try something like what I have below.  Copy and save it to a .ps1 file.  Call it from powershell like this:

    & .\Approve-WSUSUpdatesFromFile.ps1 -WsusServer myserver -ApprovedUpdateFile ".\UpdatesToApprove.txt" -WSUSGroup "SERVER2008-R2-SP1 Deployment"


    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true,
                    Position=0)]
        $WsusServer,
        [int]
        $Port = "80",
        [Parameter(Mandatory=$true)]
        [ValidateScript({Test-Path $_ -PathType ‘Leaf’})] 
        [string]
        $ApprovedUpdateFile,
        [Parameter(Mandatory=$true)]
        [string]
        $WSUSGroup
    )
    
    Begin {
        Connect-PoshWSUSServer -WsusServer $WsusServer -port $Port
    }
    Process {
        if ($ApprovedUpdateFile) {
            Get-Content $ApprovedUpdateFile | Foreach {
                Get-PoshWSUSUpdate $_ | Approve-PoshWSUSUpdate -Action Install -Group $WSUSGroup –PassThru
            }
        }
        Else {
            Write-Warning "No Updates found to approve."
        }
    }
    End {
        Disconnect-PoshWSUSServer
    }



    • Edited by Brian Klish Thursday, July 7, 2016 2:29 AM forgot the $WSUSGroup param
    • Marked as answer by Yaqoop Hadadi Sunday, July 10, 2016 9:06 AM
    Thursday, July 7, 2016 2:27 AM
  • Actually my If statement is pointless since the parameter is mandatory.  Originally wrote it differently.  Also no point having the begin, process, or end blocks since I'm not accepting input from pipeline.  Originally I was going to so I wrote it that way.  This makes more sense:

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true,
                    Position=0)]
        [string]
        $WsusServer,
        [int]
        $Port = "80",
        [Parameter(Mandatory=$true)]
        [ValidateScript({Test-Path $_ -PathType ‘Leaf’})] 
        [string]
        $ApprovedUpdateFile,
        [Parameter(Mandatory=$true)]
        [string]
        $WSUSGroup
    )
    
    Connect-PoshWSUSServer -WsusServer $WsusServer -port $Port
    
    Get-Content $ApprovedUpdateFile | Foreach {
        Get-PoshWSUSUpdate $_ | Approve-PoshWSUSUpdate -Action Install -Group $WSUSGroup –PassThru
    }
    
    Disconnect-PoshWSUSServer


    • Marked as answer by Yaqoop Hadadi Sunday, July 10, 2016 9:06 AM
    Friday, July 8, 2016 12:50 PM
  • Dear Brian,

    Thank you for the script but in

    ".\UpdatesToApprove.txt" do I have to create this txt file and put the list of KB id on it ? and in

    -WsusServer myserver do I have to replace myserver to my server name?

    Thanks.

    Saturday, July 9, 2016 5:03 PM
  • yes and yes
    Saturday, July 9, 2016 9:43 PM
  • Dear Brian,

    I receive the error below:

    Get-PoshWSUSUpdate : The term 'Get-PoshWSUSUpdate' is not recognized as the name of a cmdlet, function, script file,
    or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
    try again.
    At .\Approve-WSUSUpdatesFromFile.ps1:21 char:5
    +     Get-PoshWSUSUpdate $_ | Approve-PoshWSUSUpdate -Action Install -Group $WSUSG ...
    +     ~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (Get-PoshWSUSUpdate:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException

    Monday, July 18, 2016 8:15 AM
  • Dear Brian,

    I receive the error below:

    Get-PoshWSUSUpdate : The term 'Get-PoshWSUSUpdate' is not recognized as the name of a cmdlet, function, script file,
    or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
    try again.
    At .\Approve-WSUSUpdatesFromFile.ps1:21 char:5
    +     Get-PoshWSUSUpdate $_ | Approve-PoshWSUSUpdate -Action Install -Group $WSUSG ...
    +     ~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (Get-PoshWSUSUpdate:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException

    Did you download and install/import the PoshWSUS modules?

    PS: it's been moved and renamed now: https://github.com/proxb/PoshWSUS


    Don [doesn't work for MSFT, and they're probably glad about that ;]

    Monday, July 18, 2016 8:23 AM
  • Yep I mentioned you'll need the PoshWSUS module above.  Thanks for pointing out the new version on github Don.  I wasn't aware it moved and changed some.  I updated my script to work with and require the new module version:

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true,
                    Position=0)]
        [string]
        $WsusServer,
        [int]
        $Port = "80",
        [Parameter(Mandatory=$true)]
        [ValidateScript({Test-Path $_ -PathType ‘Leaf’})] 
        [string]
        $ApprovedUpdateFile,
        [Parameter(Mandatory=$true)]
        [string]
        $WSUSGroup
    )
    
    #Requires -Modules @{ModuleName="PoshWSUS";ModuleVersion="2.3.1.2"}
    
    Connect-PSWSUSServer -WsusServer $WsusServer -port $Port
    
    $Groups = Get-PSWSUSGroup -Name $WSUSGroup
    Get-Content $ApprovedUpdateFile | Foreach {
        Get-PSWSUSUpdate $_ | Approve-PSWSUSUpdate -Action Install -Group $Groups –PassThru
    }
    
    Disconnect-PSWSUSServer

    Can be called the same way as before:

    & .\Approve-WSUSUpdatesFromFile.ps1 -WsusServer MyWsusServer -ApprovedUpdateFile "C:\ApprovedUpdates.txt" -WSUSGroup "SERVER2008-R2-SP1 Deployment" -port "8530"

    Monday, July 18, 2016 5:45 PM