Script to check specific patches on Window 7 systems

This topic contains 4 replies, has 3 voices, and was last updated by  Neville D’Souza 4 months, 2 weeks ago.

  • Author
    Posts
  • #90613

    Neville D’Souza
    Participant

    Hi All,

    I am trying to get a powershell script to test windows 7 systems for existence of certain patches in some OU and export the result of all systems which don't have the patches to csv. I have got this far but dont get any output in the csv. I think also need to run Enable-PSRemoting on these systems.Can anyone help me please?

    $systemsInOU = Get-ADComputer -Properties Name, OperatingSystem, OperatingSystemVersion, LastLogonDate -Filter { Enabled -eq $True } -SearchBase "OU=SomeOU,DC=Domain,DC=org,DC=uk" |
                    Where-Object { Test-Connection $_.Name -Count 1 -Quiet } |
                    Select-Object -Property Name, OperatingSystem, OperatingSystemVersion, canonicalName, LastLogonDate
    
    foreach ($system in $systemsInOU) {
        try {
            $isPatched = Invoke-Command -ComputerName $system.Name -ErrorAction Stop -ScriptBlock {
                $patches = 'KB976373', 'KB980295', 'KB2481614', 'KB2491809', 'KB2494172', 'KB2736878', 'KB2835595' #Check Windows 7 Patches for dot1x
    
                if (Get-HotFix -Id $Patches -ErrorAction SilentlyContinue) {
                    $true
                } else {
                    $false
                }
            }
            
            if (-not $isPatched) {
                Get-CimInstance Win32_ComputerSystem -ComputerName $system.Name |
                    Select-Object *,
                        @{Name="Model";     Expression={ $_.Model }},
                        @{Name="UserName";  Expression={ $_.UserName }},
                        @{Name="IPAddress"; Expression={ (Resolve-DnsName -Name $_.Name).IPAddress }},
                        @{Name="IsPatched"; Expression={ $isPatched }} |
                    Export-Csv -Path C:\Scripts\NoDot1xpatches.csv -NoTypeInformation -Append
            }
        } catch {
            Write-Warning "Failed to connect to $($system.Name) ($($_.Exception.Message))"
        }
    }
    
  • #90623

    Don Jones
    Keymaster

    Well, I'm not able to run your script in my environment, but I can make some guesses.

    Windows 7 may not enable WS-MAN – and therefore CIM – by default. This isn't PSRemoting per se, but it's similar. You might try using the legacy Get-WmiObject instead if Win7 is your only target.

    Invoke-Command definitely requires PSRemoting to be enabled. You might consider reading "Secrets of PowerShell Remoting" for guidance on mass-setup of PSRemoting via GPO, if you'd like to go that route.

    I'd also add some verbose or debug output so I could what was happening at each step, and what my variable contained. "Learn PowerShell Scripting in a Month of Lunches" has an excellent (if I do say so myself) chapter on debugging.

  • #90757

    Neville D’Souza
    Participant

    Thanks Don,

    I did some research and tried doing one bit at a time and created my own logic. So far I got the small bits working but I need some help to put it all together.Here's my logic.

    Get all the windows 7 systems in a variable

    $MachinesInOU = Get-ADComputer -SearchBase 'OU=SomeOU,DC=Domain,DC=ORG,dc=UK' -Filter { OperatingSystem -Like 'Windows 7 Enterprise' } -Properties OperatingSystem | Select Name
    

    Next create a foreach loop to check for updates

    $hotfixes = "KB976373", "KB980295", "KB2481614", "KB2491809", "KB2494172", "KB2736878", "KB2835595"  
    $hotfix = Get-HotFix -computername $Machine | Where-Object {$hotfixes -contains $_.HotfixID} | Select-Object -property "HotFixID" 
    if (Get-HotFix | Where-Object {$hotfixes -contains $_.HotfixID}) { "Found HotFix: " + $hotfix.HotFixID } 
    else { "Did not Find HotFix" }	
    

    If no updates are found then give me the system info

    Get-WmiObject win32_operatingsystem -ComputerName $Machine |
                    Select-Object @{Name="ComputerName";Expression={ $_.csname }},`
                                  @{Name="Model";Expression={ (Get-WMIObject -ComputerName $Machine -class Win32_ComputerSystem).Model }},`
                                  @{Name="UserName";Expression={ (Get-WMIObject -ComputerName $Machine -class Win32_ComputerSystem).UserName }},`
                                  @{Name="IPAddress";Expression={ (Test-Connection $Machine -count 1).Ipv4Address }},`
                                  @{Name="WindowsVersion";Expression={ $_.caption }}
    
    

    Can anyone help me with this? Any suggestions are welcome.

  • #90818

    postanote
    Participant

    Taking what you've done here, this would be my approach at the same task

    
        Clear-Host
        # Grab an computer OU from AD and get the DistinguishedName as input for the SearchBase
        # Filter for a OS type and get the NetBIOS name of the computers
        $SearchBase = (Get-ADOrganizationalUnit -Filter *).DistinguishedName[0]
    
        # Set pacth list to check 
        $HotfixList = "KB976373", "KB980295", "KB2481614", "KB2491809", "KB2494172", "KB2736878", "KB2835595"
    
        # Filter for a OS type and get the NetBIOS name of the computers
        $TargetHosts = (Get-ADComputer -SearchBase $SearchBase -Filter {OperatingSystem -Like '*server*'}).Name
    
        ForEach ($TargetHost  in $TargetHosts )
        {
            "`nProcessing validation on $TargetHost ********* `n"
            $HotfixCounter = 0
    
            ForEach ($Hotfix in $HotfixList)
            {
                #"`nValidating hotfix $Hotfix on host"
    
                If (Get-HotFix $TargetHost -ErrorAction SilentlyContinue)
                {"Hotfix $Hotfix is present"}
                Else 
                {
                    Write-Warning -Message "Hotfix $HotFix not on host"
                    $HotfixCounter ++
                }
            }
       
            "$TargetHost has a missing hotfix count of $HotfixCounter. Displaying host details"
    
            Get-WmiObject win32_operatingsystem -ComputerName $TargetHost |
            Select-Object @{Name="ComputerName";Expression={ $TargetHost.Name }},`
                            @{Name="Model";Expression={ (Get-WMIObject -ComputerName $TargetHost -class Win32_ComputerSystem).Model }},`
                            @{Name="UserName";Expression={ (Get-WMIObject -ComputerName $TargetHost -class Win32_ComputerSystem).UserName }},`
                            @{Name="IPAddress";Expression={ (Test-Connection $TargetHost -count 1).Ipv4Address }},`
                            @{Name="WindowsVersion";Expression={ $TargetHost.caption }}
        }
    
    
        Results 
    
        Processing validation on DC01 ********* 
    
        WARNING: Hotfix KB976373 not on host
        WARNING: Hotfix KB980295 not on host
        WARNING: Hotfix KB2481614 not on host
        WARNING: Hotfix KB2491809 not on host
        WARNING: Hotfix KB2494172 not on host
        WARNING: Hotfix KB2736878 not on host
        WARNING: Hotfix KB2835595 not on host
        DC01 has a missing hotfix count of 7. Displaying host details
    
    
        ComputerName   : 
        Model          : HVM...
        UserName       : 
        IPAddress      : 192.168...
        WindowsVersion : 
    
    
    

    Again, this is quick edit effort, and I have no Win7 anywhere in my environment, but the premise should be the same.

  • #91027

    Neville D’Souza
    Participant

    Thank you very much. This exactly what I wanted. I have modified it to my needs and works very well.

    Clear-Host
        # Grab an computer OU from AD and get the DistinguishedName as input for the SearchBase
        # Filter for a OS type and get the NetBIOS name of the computers
        $SearchBase = (Get-ADOrganizationalUnit -Filter *).DistinguishedName[48]
    
        # Set patch list to check 
        $HotfixList = "KB976373", "KB980295", "KB2481614", "KB2491809", "KB2494172", "KB2736878", "KB2835595"
    
        # Filter for a OS type and get the NetBIOS name of the computers
        $TargetHosts = (Get-ADComputer -SearchBase $SearchBase -Filter {OperatingSystem -Like 'Windows 7 Enterprise'}).Name
    
        ForEach ($TargetHost  in $TargetHosts )
        {
            "`nProcessing validation on $TargetHost ********* `n"
            $HotfixCounter = 0
    
            ForEach ($Hotfix in $HotfixList)
            {
                #"`nValidating hotfix $Hotfix on host"
    
                If (Get-HotFix -computername $TargetHost -ErrorAction SilentlyContinue)
                {"Hotfix $Hotfix is present"}
                Else 
                {
                    Write-Warning -Message "Hotfix $HotFix not on host"
                    $HotfixCounter ++
                }
            }
       
            "$TargetHost has a missing hotfix count of $HotfixCounter. Displaying host details"
    
            $CustomResult = Get-WmiObject win32_operatingsystem -ComputerName $TargetHost |
                                Select-Object @{Name="ComputerName";Expression={ (Get-WMIObject -ComputerName $TargetHost -class Win32_operatingsystem).PSComputerName }},`
                                    @{Name="Model";Expression={ (Get-WMIObject -ComputerName $TargetHost -class Win32_ComputerSystem).Model }},`
                                    @{Name="UserName";Expression={ (Get-WMIObject -ComputerName $TargetHost -class Win32_ComputerSystem).UserName }},`
                                    @{Name="IPAddress";Expression={ (Test-Connection $TargetHost -count 1).Ipv4Address }},`
                                    @{Name="WindowsVersion";Expression={ (Get-WMIObject -ComputerName $TargetHost -class win32_operatingsystem).caption }},`
                                    @{Name="MissingPatches";Expression={[string]$HotfixCounter}} 
            $CustomResult | Export-CSV "C:\\scripts\NoDot1xpatches.csv" -NoTypeInformation -Append -Encoding UTF8
              
        } 
    

You must be logged in to reply to this topic.