Search code examples
powershellwmivpn

Unable to run Get-WmiObject on machine connected via Direct Connect VPN


$adminaccount = "DOMAIN\USERNAME"
$PASSWORD = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
$UNPASSWORD = New-Object System.Management.Automation.PsCredential $adminaccount, $PASSWORD

$Machines = Get-Content -Path "C:\Temp\production computers.txt"

$Result = Foreach ($Machine in $Machines){
New-Object -TypeName PSObject -Property @{
$hardware =  Get-WmiObject Win32_ComputerSystem -ComputerName $Machine -Credential $UNPASSWORD
$os =  Get-WmiObject Win32_OperatingSystem -ComputerName $Machine -Credential $UNPASSWORD
Computer = $Machine
Manufacturer = $hardware.Manufacturer
Model = $hardware.Model
OS = $os.Caption
}| Select-Object Computer,Manufacturer,Model,OS
}

$Result | Export-Csv -Path "C:\Temp\pcsinventory.csv" -NoTypeInformation

Trying to run the above to gather information from a list of machines, got two issues: Firstly I can get information back from machines connected to the network directly but the machines we have on Direct Connect VPNs get an "unable to contact RPC Server" error from the Get-WmiObjectcommand ; Secondly the results I do get seem to all come out as the same, when I know they're different, so somethings going wrong there.


Solution

  • Try using CIM cmdlets instead of legacy Get-WMIObject. In this case, Get-CimInstance can be a direct substitute.

    I'm guessing there's a firewall issue given the different network paths. `Get-WMIObject is deprecated in Windows PowerShell and removed from PowerShell Core.

    Straight forward example:

    $adminaccount = "DOMAIN\USERNAME"
    $PASSWORD     = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
    $UNPASSWORD   = New-Object System.Management.Automation.PsCredential $adminaccount, $PASSWORD
    $hwProps      = 'manufacturer','Model'
    
    $Machines = Get-Content -Path "C:\Temp\production computers.txt"
    
    $Result = Foreach ($Machine in $Machines){
        $hw =  Get-CimInstance Win32_ComputerSystem -ComputerName $Machine -Property $hwProps -Credential $UNPASSWORD
        $os =  Get-CimInstance Win32_OperatingSystem -ComputerName $Machine -Credential $UNPASSWORD
        
        [PSCustomObject]@{    
            Computer     = $Machine
            Manufacturer = $hw.Manufacturer
            Model        = $hw.Model
            OS           = $os.Caption
        }
    }
    
    $Result | Export-Csv -Path "C:\Temp\pcsinventory.csv" -NoTypeInformation
    

    I changed a little syntax, using the newer [PSCustomObject] casting. I also moved the I WMI queries out of the custom object declaration. They don't need to be there, and by doing so you don't need the Select-Object command. This is because now the only properties in the object are the ones you would have selected anyway.

    Even if Cim doesn't solve the problem it's really the way to go. Take a look at Introduction to CIM CMdlets which will give you a good start...

    Update to use Credentials with CIM:

    $adminaccount = "DOMAIN\USERNAME"
    $PASSWORD     = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
    $UNPASSWORD   = New-Object System.Management.Automation.PsCredential $adminaccount, $PASSWORD
    $hwProps      = 'manufacturer','Model'
    
    $Machines = Get-Content -Path "C:\Temp\production computers.txt"
    
    $Result = Foreach ($Machine in $Machines){
        $CimSession = New-CimSession -ComputerName $Machine -Credential $UNPASSWORD
        $hw =  Get-CimInstance Win32_ComputerSystem -CimSession $CimSession -Property $hwProps
        $os =  Get-CimInstance Win32_OperatingSystem -CimSession $CimSession
        
        [PSCustomObject]@{    
            Computer     = $Machine
            Manufacturer = $hw.Manufacturer
            Model        = $hw.Model
            OS           = $os.Caption
        }
    }
    
    $Result | Export-Csv -Path "C:\Temp\pcsinventory.csv" -NoTypeInformation
    

    Update above uses New-CimSession with the -Credential parameter. Then it specs the-CimSession $CimSession instead of -ComputerName.... The credentials were overlooked in my initial example. Note: Using a CIM session is actually more efficient than repeating commands with -ComputerName.... The latter creates a CIM session under the hood, so each iteration creates and tears down a session, by reusing a session you do that fewer times...