Using #PWSH to validate desktop connectivity from Active Directory


Been busy with rolling out new Windows 10 desktop workstations for an organization and making sure that this new rollout is fully managable for their administrators.
So I asked myself a few simple supportability questions if I’m an administrator looking after a large environment on what do I need to make my life easier at work.

What will you do when someone asks you in IT department to find any workstation to check if they are online?
I will PowerShell a probe against all workstations within an Organization Unit (OU) from Active Directory.

What will I want to know?

  • The Hostname of the desktop workstation
  • The Operating System of the desktop workstation
  • The Operating System Version of the desktop workstation
  • When it has joined the domain which is a rough indicator of when it is provisioned or deployed
  • When it has changed in the domain which is a rough indicator of when the computer object in Active Directory was modified
  • When the machine has last established an authentication in the domain
  • Validate if the hostname is pingable
  • What is the Fully Qualified Domain Name for the computer
  • Validate if the FQDN of the computer is pingable
  • Resolve the IP Address based on the FQDN of the computer
  • Validate the IP Address is pingable
  • Validate the WMI is reachable for WMI query
  • Validate the WinRM is reachable for PowerShell Remoting
  • Validate the Remote Desktop Protocol (RDP) is reachable for Remoting
  • Validate the UNC Path to C:\ drive is reachable or accessible

And here it is my #PWSH PowerShell quick adventure in 10mins…

What do I need?
Active Directory PowerShell Module (To find out how to get it on Windows 10, follow here)

Import-Module -Name ActiveDirectory ;

Next I will need to grab all the Computer Objects from Active Directory.

Get-ADComputer and the Distinguised Name of the Organization Unit (OU) where all my desktop workstations are contained as the search base.

Get-ADComputer `
    -SearchBase "OU=Win10,OU=Workstations,DC=amce,DC=co,DC=nz" `
    -Filter * `
    -Properties * ;

That’s simple enough but it doesn’t achieve my goal on what I need to know.

Therefore, I have to loop the array of computer objects received from Get-ADComputer and pipelined to a ForEach-Object to interrogate each computer object with additional custom information as below with Test-Connection, Test-WSMan, Test-Path, Get-WMIObject and others…

Import-Module `
    -Global ActiveDirectory ;

Get-ADComputer `
    -SearchBase "OU=Win10,OU=Workstations,DC=amce,DC=co,DC=nz" `
    -Filter * `
    -Properties * | `
        ForEach-Object { `
            $_ | Select-Object `
            Name, `
            OperatingSystem, `
            OperatingSystemVersion, `
            whenCreated, `
            whenChanged, `
            LastLogonDate, `
            @{ `
                N='HostnamePingable'; `
                E={ `
                    Test-Connection `
                        -ComputerName $_.Name `
                        -Count 1 `
                        -Quiet ; `
                  } `
            },`
            DNSHostname, `
            @{ `
                N='FQDNPingable'; `
                E={ `
                    Test-Connection `
                        -ComputerName $_.DNSHostname `
                        -Count 1 `
                        -Quiet ; `
                  } `
            }, `
            @{ `
                N='IPv4Address'; `
                E={ `
                    [System.Net.Dns]::GetHostAddresses($_.DNSHostname) | `
                        Select-Object `
                            -ExpandProperty IPAddressToString ; `
                  } `
            }, `
            @{ `
                N='IPv4Pingable'; `
                E={ `
                    Test-Connection `
                        -ComputerName ([System.Net.Dns]::GetHostAddresses($_.DNSHostname) | `
                            Select-Object `
                                -ExpandProperty IPAddressToString) `
                        -Count 1 `
                        -Quiet ; `
                   } `
            }, `
            @{ `
                N='WMIReachable'; `
                E={ `
                    $result = Get-WmiObject `
                        -ComputerName $_.DNSHostname `
                        -Class Win32_OperatingSystem `
                        -ErrorVariable err ;
                    if($err -match (Out-Null)){ `
                        $false ; 
                    }else{ `
                        $true ;
                    } `
                  } `
            }, `
            @{ `
                N='WinRMReachable'; `
                E={ `
                    try{ `
                        Test-WSMan `
                            -ComputerName $_.DNSHostname | `
                                Out-Null; 
                        $true ;
                    }catch{ `
                        $false ;
                    } `
                  } `
            }, `
            @{ `
                N='RDPReachable'; `
                E={ `
                    try{ `
                        (New-Object System.Net.Sockets.TCPClient `
                            -ArgumentList $_.DNSHostname,3389).Connected `
                    }catch{ `
                        $false ;
                    } `
                  } `
            }, `
            @{ `
                N='C$Reachable'; `
                E={ `
                    Test-Path `
                        -Path ('\\' + $_.Name + '\C$') ; `
                  } `
            } `
        } | Out-GridView ;

Finally, I will pipelined the result to a Out-GridView for viewing purposes.

Leave a comment