27 February 2015

Cleaning up old systems in Active Directory, SCCM, and Antivirus

Every place I have worked, there has been the issue of systems being in SCCM, AD, and antivirus that no longer existed. The is often caused by systems being overlooked when a user departs the company, a laptop that gets put in a desk and not turned on forever, and a lot of other similar scenarios.

While I was in the process of upgrading SCCM 2007 to 2012, I finally became fed up over it and wrote this script. The script uses All Systems from SCCM as the master list. Here is why. The way I have the SCCM configured is that All Systems is populated by AD. Logically, that means that even if a system has been deleted in AD, it might still be present in SCCM. We use a third party antivirus, so I integrated it by importing a list of all systems it showed with the antivirus client.

The script will first read a system from the SCCM list named SCCMSystems.txt. It reads the antivirus systems from a text file called AntivirusSystems.txt. The text files should be in UTF-8 format. It then runs through three tests. The first test is to query AD. The second test is to check if the system name is included in the antivirus list. The third test is to run a network connectivity test. If the network connectivity test fails, it runs a secondary ping test and reads the output of ping.exe to see if it returns host not found. The Network Connectivity test fails only if a host not found is returned. It passes for any other message because it could be a laptop that is offline at the time.

There is a csv file that is written to for all failures. The csv file contains two primary columns, deletions and additions. Under the deletions, it has AD, antivirus, and SCCM. Under the additions if antivirus. An X is placed in each box indicating the recommended action.

If you do not want/need the antivirus, you can delete that portion out of the script. This script is only a primer for instituting in your organization. It will need to be adapted to your network.

You can download the script from here.




 <#  
 .SYNOPSIS  
   ValidateSystems  
 .DESCRIPTION  
   Validate if a system still exists  
 .Author  
   Mick Pletcher  
 .Date  
   26 February 2015  
 .EXAMPLE  
   powershell.exe -executionpolicy bypass -file ValidateSystems.ps1  
 #>  
   
 Function InitializeGlobalMemory {  
      Set-Variable -Name Computers -Scope Global -Force  
      Set-Variable -Name Logfile -Scope Global -Force  
      Set-Variable -Name RelativePath -Scope Global -Force  
      Set-Variable -Name Webroot -Scope Global -Force  
      $Global:Failures = @()  
      $Global:RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent)+"\"   
      $Global:LogFile = $Global:RelativePath + "Output.csv"  
      $Global:Computers = Get-Content -Path $Global:RelativePath"SCCMSystems.txt" -Force  
      $Global:Webroot = Get-Content -Path $Global:RelativePath"AntivirusSystems.txt" -Force  
   
 }  
   
 Function ProcessLogFile {  
      If ((Test-Path $Global:LogFile) -eq $true) {  
           Remove-Item $Global:LogFile -Force  
      }  
      If ((Test-Path $Global:LogFile) -eq $false) {  
           $temp = New-Item $Global:LogFile -ItemType File -Force  
           $Output = ","+"Deletions"+","+","+","+"Additions"  
           Out-File -FilePath $Global:LogFile -InputObject $Output -Append -Force -Encoding UTF8  
           $Output = "Computer Name"+","+"Active Directory"+","+"SCCM"+","+"Antivirus"+","+"Antivirus"  
           Out-File -FilePath $Global:LogFile -InputObject $Output -Append -Force -Encoding UTF8  
      }  
 }  
   
 Function ProcessComputers {  
      $obj = New-Object PSObject  
      $Count = 0  
      Foreach ($Computer in $Global:Computers) {  
           cls  
           $Antivirus = $false  
           $Count += 1  
           Write-Host "Processing "$Count" of " -NoNewline  
           Write-Host $Global:Computers.Count  
           Write-Host  
           Write-Host "Computer Name: "$Computer  
           $ADAccount = $null  
           #Active Directory  
           Write-Host "Testing AD Presence....." -NoNewline  
           $ErrorActionPreference = 'SilentlyContinue'  
           $ADAccount = Get-ADComputer $Computer  
           If ($ADAccount -eq $null) {  
                $ADAccount = $false  
                Write-Host "Does not Exist" -ForegroundColor Red  
           } else {  
                $ADAccount = $true  
                Write-Host "Exists" -ForegroundColor Yellow  
           }  
           #Antivirus  
           Write-Host "Testing Antivirus....." -NoNewline  
           Foreach ($system in $Global:Webroot) {  
                If ($system -eq $Computer) {  
                     $Antivirus = $true  
                }  
           }  
           If ($Antivirus -eq $true) {  
                Write-Host "Exists" -ForegroundColor Yellow  
           } else {  
                Write-Host "Does not exist" -ForegroundColor Red  
           }  
           #Network Connectivity  
           Write-Host "Testing Network Connectivity....." -NoNewline  
           If ((Test-Connection -ComputerName $Computer -Quiet) -eq $false) {  
                $NetworkTest = ping $Computer  
                If ($NetworkTest -like '*Ping request could not find host*') {  
                     $NetworkTest = $false  
                     Write-Host "Does not exist" -ForegroundColor Red  
                } else {  
                     $NetworkTest = $true  
                     Write-Host "Exists" -ForegroundColor Yellow  
                }  
           } else {  
                $NetworkTest = $true  
                Write-Host "Exists" -ForegroundColor Yellow  
           }  
           If (($ADAccount -eq $true) -and ($NetworkTest -eq $false)) {  
                #Write-Host $Computer -NoNewline  
                #Write-Host " - Delete from AD and SCCM" -BackgroundColor Yellow -ForegroundColor Black  
                $obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer  
                If ($Antivirus -eq $true) {  
                     $obj | Add-Member -MemberType NoteProperty -Name Action -Value "AD_SCCM_Antivirus"  
                } else {  
                     $obj | Add-Member -MemberType NoteProperty -Name Action -Value "AD_SCCM"  
                }  
           }  
           If (($ADAccount -eq $false) -and ($NetworkTest -eq $false)) {  
                #Write-Host $Computer -NoNewline  
                #Write-Host " - Delete from SCCM" -BackgroundColor Green -ForegroundColor Black  
                $obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer  
                If ($Antivirus -eq $true) {  
                     $obj | Add-Member -MemberType NoteProperty -Name Action -Value "SCCM_Antivirus"  
                } else {  
                     $obj | Add-Member -MemberType NoteProperty -Name Action -Value "SCCM"  
                }  
           }  
           If (($ADAccount -eq $true) -and ($NetworkTest -eq $true) -and ($Antivirus -eq $false)) {  
                $obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer  
                $obj | Add-Member -MemberType NoteProperty -Name Action -Value "AddAntivirus"  
           }  
           If ($obj -ne $null) {  
                $Global:Failures += $obj  
                $Output = $obj.ComputerName  
                If ($obj.Action -eq "AD_SCCM") {  
                     $Output = $Output + ","+"X"+","+"X"   
                }  
                If ($obj.Action -eq "AD_SCCM_Antivirus") {  
                     $Output = $Output + ","+"X"+","+"X"+","+"X"  
                }  
                If ($obj.Action -eq "SCCM") {  
                     $Output = $Output + ","+","+"X"  
                }  
                If ($obj.Action -eq "SCCM_Antivirus") {  
                     $Output = $Output + ","+","+"X"+","+"X"  
                }  
                If ($obj.Action -eq "AddAntivirus") {  
                     $Output = $Output + ","+","+","+","+"X"  
                }  
                Out-File -FilePath $Global:LogFile -InputObject $Output -Append -Force -Encoding UTF8  
                Remove-Variable -Name obj  
                $obj = New-Object PSObject  
           }  
           Start-Sleep -Seconds 1  
      }  
 }  
   
 Function WriteToScreen {  
      cls  
      Foreach ($Failure in $Global:Failures) {  
           If ($Failure -ne $null) {  
                Write-Output $Failure  
           }  
      }  
      $ErrorActionPreference = 'Continue'  
 }  
   
 cls  
 Import-Module -Name ActiveDirectory  
 InitializeGlobalMemory  
 ProcessLogFile  
 ProcessComputers  
 WriteToScreen  
   

0 comments:

Post a Comment