PowerShell Return computer name count of missing updates missing KBs

Hi Experts,

Thanks for all to share your ideas and great suggestion. I’m just learning start PS. I need your help and suggestion on my below query. We are using Wsus server for deploying the patches on domain systems. We need to check the status of few security patches has been installed or failed on a network system. We are checking with WSUS report, but that is a very lengthy process and need to do work on excel file and share the report with the manager. We have used the below script and this will works fine for us, but I have no idea how to export that PS output in CSV or TEXT file.

Please refer the below script and help us on this issue.

Thanks & Regards,

Vishal

Clear-Host

# Path to files
$filePath = "C:\scripts"

# the computers to check
$computerList = Get-Content -Path "$filePath\computers.txt"

# the KBs to check
$patchList = Get-Content -Path "$filePath\KBs.txt"

$E_Total = "" # exists total
$NE_Total = "" # not exists total
$Count = 0 # missing updates counter
$BoolCheck = 0


foreach ($computer in $computerList)
{

# is machine online?
$Ping = test-connection -ComputerName $computer -Count 2 -quiet

# yes, online
if($Ping)
{

# get current list of hotfixes on machine
$HotfixList = Get-HotFix -ComputerName $computer | select -Property "HotFixID"

# cycle through each patch in list
foreach($patch in $patchList)
{
$BoolCheck=0


# cycle through hotfixes on local machine
foreach ($Hotfix in $HotfixList)
{

# compare local machine hotfixes with our list
# if it matches, exists
if ($patch -eq $Hotfix.HotFixID)
{
$BoolCheck=1
break
}


}

if ($found -eq 1) {
$E_Total = "$E_Total,$patch"
}

if ($BoolCheck -eq 0) {
# $patch
$NE_Total = "$NE_Total,$patch"
$Count=$Count+1
}

}
# Write-Host "Found: $Computer$E_Total"
Write-Host "$Computer,Missing $count$NE_Total"
Write-Host " "

# Clear session
$E_Total = ""
$NE_Total = ""
$Count = 0
$BoolCheck = 0


}

# no, not online
else
{
Write-Host "$Computer,Not Online"
Write-Host " "
}
}

  • This sounds like you are new to PoSH. So, see this post about how to get up to speed, so you can eliminate some of the frustration / confusion you are having.

         'reddit.com/r/PowerShell/comments/7oir35/help_with_teaching_others_powershell'
        'idera.com/resourcecentral/whitepapers/powershell-ebook/thankyou'

    Anyway, as to you current query. This is what the Redirect options and output cmdlets are specifically designed for.

        # Get parameters, examples, full and Online help for a cmdlet or function

        (Get-Command -Name Export-Csv).Parameters
        Get-help -Name Export-Csv -Examples
        Get-help -Name Export-Csv -Full
        Get-help -Name Export-Csv -Online

        Get-Help about_*

        See also:
        Get-Help about_Redirection
        Get-Help about_Functions

        # Find all cmdlets / functions with a target parameter
        Get-Help * -Parameter Append

        # All Help topics locations
        explorer "$pshome\$($Host.CurrentCulture.Name)"

    Remove al the Write-Host stuff as that empties the buffer and thus cannot be used
    later for output.


    This ...

        Write-Host "$Computer,Not Online"

    and this...


        "$Computer,Not Online"

    Do exactly the same thing. Output to the screen is the default, unless you tell
    it otherwise.


        Using Write-Host has been a hotly debated topic for a long while. Even by the
        inventor / author of PowerShell.


        Write-Host Considered Harmful - by PowerShell founder Jeffrey Snover

        'jsnover.com/blog/2013/12/07/write-host-considered-harmful'

        When you are writing or reviewing PowerShell scripts, I’d like you to remember
        the following rule of thumb:

         Using Write-Host is almost always wrong.

        Write-Host is almost always the wrong thing to do because it interferes with
        automation. There are typically two reasons why people use Write-Host:

        Lot's of other articles exist on the topic. In earlier versions of PoSH,
        Write-Host could not be used in pipeline, as the moment yo use it the data is
        gone from the buffer.


        However, in PoSHv5 Jeffrey Snover now says...

        With PowerShell v5 Write-Host no longer "kills puppies". data is captured into
        info stream

        'docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Write-Information?view=powershell-5.1'

        Description

        The Write-Information cmdlet specifies how Windows PowerShell handles information
        stream data for a command.

        Windows PowerShell 5.0 introduces a new, structured information stream (number
        6 in Windows PowerShell streams) that you can use to transmit structured data
        between a script and its callers (or hosting environment). Write-Information
        lets you add an informational message to the stream, and specify how Windows
        PowerShell handles information stream data for a command.

    Still, unless absolutely necessary (for example color text to the screen for user
    interaction stuff - even that can be worked around easily) just don't use
    Write-Host


    Just make it a function and use those options

    Something like -

        Function Get-WsusPatchReport
        {
            [CmdletBinding()]

            [Alias('gwpr')]

            Param
            (
                [string]$filePath = "C:\scripts",
                [string]$ComputerFileName = 'computers.txt',
                [string]$KBFileName = 'KBs.txt'
            )

            # the computers to check
            $computerList = Export-Csv -Path "$filePath\$ComputerFileName"

            # the KBs to check
            $patchList = Export-Csv -Path "$filePath\$KBFileName"

            $E_Total = "" # exists total
            $NE_Total = "" # not exists total
            $Count = 0 # missing updates counter
            $BoolCheck = 0


            foreach ($computer in $computerList)
            {

                # is machine online?
                $Ping = Test-Connection -ComputerName $computer -Count 2 -quiet

                # yes, online
                if($Ping)
                {
                    # get current list of hotfixes on machine
                    $HotfixList = Get-HotFix -ComputerName $computer | Select-Object -Property "HotFixID"

                    # cycle through each patch in list
                    foreach($patch in $patchList)
                    {
                        $BoolCheck=0


                        # cycle through hotfixes on local machine
                        foreach ($Hotfix in $HotfixList)
                        {

                            # compare local machine hotfixes with our list
                            # if it matches, exists
                            if ($patch -eq $Hotfix.HotFixID)
                            {
                                $BoolCheck=1
                                break
                            }
                        }

                        if ($found -eq 1)
                        {
                            $E_Total = "$E_Total,$patch"
                        }

                        if ($BoolCheck -eq 0)
                        {
                            # $patch
                            $NE_Total = "$NE_Total,$patch"
                            $Count=$Count+1
                        }
                    }

                    # "Found: $Computer$E_Total"
                    "$Computer,Missing $count$NE_Total"
                    " "

                    # Clear session
                    $E_Total = ""
                    $NE_Total = ""
                    $Count = 0
                    $BoolCheck = 0
                }
                else
                {
                    # no, not online
                    "$Computer,Not Online`n"
                }
            }
        }

        Get-WsusPatchReport | Export-Csv -Path 'C:\WsusReports\WsusData.csv'