#requires -version 2 param ( [string] $class = $(throw "The WMI Class is required."), [array] $attributes, [string] $NameSpace ) $erroractionpreference = "SilentlyContinue" $thisScript = Split-Path $myInvocation.MyCommand.Path -Leaf $scriptRoot = Split-Path(Resolve-Path $myInvocation.MyCommand.Path) $OutPutCSVFile = Join-Path $scriptRoot "WMIInventory.csv" #Default WMI Name Space is "Root\CIMV2" if ($NameSpace -eq $null) {$NameSpace = "Root\CIMV2"} function CheckComputerConnectivity($computer) { $result = $false #check if the computer can be pinged. "checking $computer" $ping = New-Object Net.NetworkInformation.Ping $PingResult = $ping.send($computer) if ($PingResult.Status.Tostring().ToLower() -eq "success") { $result = $true } else { Write-Host "$computer cannot be reached" } return $result } function GetServersFromOU([string]$strDomainName, [array]$arrOUs, [array]$arrExcludedOus) { $arrDCs = $strDomainName.split(".") $strFullDC = $null foreach ($DC in $arrDCs) { if ($strFullDC -eq $null) { $strFullDC = "DC=$DC" } else { $strFullDC = "$strFullDC,DC=$DC" } } #Get the Distingushed Names for Excluded OUs if ($arrExcludedOus -ne $null) { for ($i=0; $i -le ($arrExcludedOus.count-1); $i++) { $arrExcludedOus[$i] = $arrExcludedOus[$i] + ",$strFullDC" } } $arrComputers = @( ) foreach ($Ou in $arrOUs) { $strFilter = "computer" $objDomain = New-Object System.DirectoryServices.DirectoryEntry $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = "LDAP://$OU,$strFullDC" $objSearcher.SearchScope = "subtree" $objSearcher.PageSize = 3000 $objSearcher.Filter = "(objectCategory=$strFilter)" $colResults = $objSearcher.FindAll() foreach ($item in $colResults) { $objComputer = $item.GetDirectoryEntry() #Only add the computer to the array if it is not in the excluded OUs. $bCorrectOU = $true foreach ($Ou in $arrExcludedOus) { if ($objComputer.distinguishedName.tostring() -match $Ou) { $bCorrectOU = $false #Write-Host "$bCorrectOU, $objComputer.distinguishedName.tostring()" } } if ($bCorrectOU -eq $true) { $arrComputers += $objComputer.Name } } } $arrcomputers = $arrcomputers | Sort-Object return $arrComputers } $strDomain = "" $arrOUs = @( ) $ExcludedOus = @() #adding OUs $arrOus += "OU=" $arrOus += "OU=,OU=" #Adding excluded OUs $ExcludedOus += "OU=,OU=" $ExcludedOus += "OU=,OU=" #Get computers $arrComputers = GetServersFromOU $strDomain $arrOUs $ExcludedOus $arrWMI = @() #if no desired attributes is passed in, use 'select *' when querying WMI class. if ($attributes.count -eq 0 -or $attributes -eq $null) { $attributes += "*" } $strQuery = "Select" Foreach ($attribute in $attributes) { $strQuery = $strQuery + " $attribute," } $strQuery = $strQuery.substring(0, ($strQuery.length-1)) $strQuery = "$strQuery from $class" Write-Host $strQuery foreach ($computer in $arrComputers) { #Check connectivities $IsComputerAccessible = CheckComputerConnectivity $computer if ($IsComputerAccessible -eq $true) { #Get-WmiObject cannot be used because cannot set timeout for WMI queries Write-Host "Checking $computer..." $wmi = [WMISearcher]'' $wmi.options.timeout = '0:0:30' #set timeout to 30 seconds $wmi.scope.path = "\\$Computer\$NameSpace" $wmi.query = $strQuery $ColObjWMI = $wmi.get() #a collection is returned from above command Foreach ($obj in $ColObjWMI) { #Create a custom psobject to only store the properties we need (including the computer name and WMI Class) $psobjWMI = $null $psobjWMI= New-Object psobject Add-Member -InputObject $psobjWMI -membertype noteproperty -name ComputerName -value $computer Add-Member -InputObject $psobjWMI -membertype noteproperty -name WMIClass -value $class #Looping through each property and add to the custom psobject Foreach ($property in ($Obj| Get-Member -MemberType Property)) { $strProperty = $property.Name if ($strProperty.substring(0,1) -ne "_") { $strValue = $obj.$strProperty Add-Member -InputObject $psobjWMI -membertype noteproperty -name $strProperty -value $strValue } } #Adding the custom psobject to an array $arrWMI += $psobjWMI } } else { $strError = "$Computer cannot be reached." } } #Export the output array to CSV $arrWMI | Select-Object -Property * -ExcludeProperty "_*"| Sort-Object | Export-Csv -notypeinformation $OutPutCSVFile -Force