powershellregistrypingregedit

Unable to add the Ping Response to Output variable


I have written a script to export specific registry keys and the sub keys inside it with the server ping response, but my scripts works as expected but the ping response value when I add it to output it is giving null

Please help me to get the ping response value for each server.

## Clear the host
Clear-Host

## Install Export-Excel Module if it is not installed
If (-Not (Get-InstalledModule -Name ImportExcel)){
Install-Module -Name ImportExcel -ErrorAction SilentlyContinue -Force 
}

## Set Script Location
Set-Location $PSScriptRoot

## Out File Name
$FileName = "$PSScriptRoot\TCPIP_Interface_Details.xlsx"

## Get full list of servers
$Servers = GC -Path ".\Servers.txt"

## Delete if Old file exists
if (Test-Path $FileName) { Remove-Item $FileName
       write-host "$FileName has been deleted" -BackgroundColor DarkMagenta }
else { Write-host "$FileName doesn't exist" -BackgroundColor Red }

## Loop through each server
$Result = foreach ($vm in $Servers) {

## Check the Ping reponse for each server
Write-Host "Pinging Server" $vm
$Ping = Test-Connection -Server $vm -Quiet -Verbose 
    if ($Ping){Write-host "Server" $vm "is Online" -BackgroundColor Green}
    else{Write-host "Unable to ping Server" $vm -BackgroundColor Red}

## Check the Network Share path Accessibility
Write-Host "Checking Share Path on" $vm
$SharePath = Test-Path "\\$vm\E$" -Verbose
    if ($SharePath){Write-host "Server" $vm "Share Path is Accessible" -BackgroundColor Green}
    else{Write-host "Server" $vm "Share path access failed" -BackgroundColor Red}

Invoke-Command -ComputerName $vm {

## Get ChildItems under HKLM TCPIP Parameter Interface
Get-ChildItem -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces' | ForEach-Object {
          Get-ItemProperty -Path $_.PSPath | Where-Object { $_.PsObject.Properties.Name -like 'Dhcp*' }
 } | Select-Object -Property @{Name = 'ComputerName'; Expression = {$env:COMPUTERNAME+"."+$env:USERDNSDOMAIN}},
                             @{Name = 'Ping_Response'; Expression = {if($using:Ping) {'Pinging'} else {'Unable to ping'}}}, 
                             @{Name = 'Share_Path_Access'; Expression = {if($using:SharePath) {'Accessible'} else {'Not Accessible'}}},
              DhcpIPAddress, @{Name = 'DhcpNameServer'; Expression = {$_.DhcpNameServer -split ' ' -join '; '}},
              DhcpServer,    @{Name = 'DhcpDefaultGateway'; Expression = {$_.DhcpDefaultGateway -join '; '}}
}}
$Result | Select-Object * -Exclude PS*, RunspaceId

Solution

  • As commented, just change your calculated property into

    @{Name = 'Ping_Response'; Expression = {$using:Ping}}
    

    By scoping the variable $Ping with using:, it will be known in the scriptblock for Invoke-Command. Without that, the scritblock simply sees it as new, undefined variable (i.e. $null)

    If as you commented, you would rather see some text instead of just True or False, have the expression in that calculated property output whatever you want like:

    @{Name = 'Ping_Response'; Expression = {if($using:Ping) {'Pinging'} else {'Unable to ping'}}}
    

    Another way of letting the scriptblock know what $Ping is, is by adding this to the command as parameter:

    Invoke-Command -ComputerName $vm {
        param([bool]$Ping)
        # ... the rest of the scriptblock
        # now, you do not have to use the `using:` scope on $Ping
    } -ArgumentList $Ping
    


    To answer your latest comment, if pinging the machine did not work, there is really no reason to try and get properties from it using Invoke-Command. If you also want to have the non-pingables in your output, do:

    $result = foreach ($vm in $Servers) {
        $Ping = Test-Connection -Server $vm -Quiet -Verbose 
        if ($Ping) {
            # we can reach this machine, so gather the properties we need and output an object
            # the 'Ping_Response 'can now be hardcoded
            Invoke-Command -ComputerName $vm -ScriptBlock {
                Get-ChildItem -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces' | ForEach-Object {
                    Get-ItemProperty -Path $_.PSPath | Where-Object { $_.PsObject.Properties.Name -like 'Dhcp*' }
                }
            } | 
            Select-Object -Property @{Name = 'ComputerName'; Expression = {$_.PSComputerName}}, 
                                    @{Name = 'Ping_Response'; Expression = { 'Pinging' }}, 
                                    DhcpIPAddress,
                                    @{Name = 'DhcpNameServer'; Expression = {$_.DhcpNameServer -split ' ' -join '; '}},
                                    DhcpServer, 
                                    @{Name = 'DhcpDefaultGateway'; Expression = {$_.DhcpDefaultGateway -join '; '}}
        }
        else {
            # return a similar object for machines that didn't respond to Ping
            # since we cannot reach this machine, most properties will be empty
            '' | Select-Object -Property @{Name = 'ComputerName'; Expression = {$vm}}, 
                                         @{Name = 'Ping_Response'; Expression = { 'Unable to ping' }},
                                         DhcpIPAddress,DhcpNameServer,DhcpServer,DhcpDefaultGateway
        }
    }
    # output the results
    $result | Select-Object * -ExcludeProperty PS*, RunspaceId | Export-Csv -Path "C:\temp\TCPIP_Interface_Details.csv" -NoTypeInformation