'你无法在空值表达式上调用方法'错误

时间:2015-07-09 06:22:17

标签: powershell

我有一个PowerShell脚本,它将根据用户输入将TCP / IP打印机安装到多台计算机上。 脚本工作正常,但我们想添加一个安全措施,以便用户不会意外地将打印机安装到另一个子网上另一个站点的资产上。

我添加了以下功能

### Function to compare subnet of Printer and Asset
Function CheckSubnet {
    param ($PrinterIP, $ComputerName, $PrinterCaption)
    $Printer = Test-Connection -ComputerName $PrinterIP -Count 1
    $PrintIP = $Printer.IPV4Address.IPAddressToString
    $IPSplit = $PrintIP.Split(".")
    $PrinterSubnet = ($IPSPlit[0]+"."+$IPSplit[1]+"."+$IPSplit[2])
    $getip = Test-Connection -ComputerName $ComputerName -Count 1 
    $IPAddress = $getip.IPV4Address.IPAddressToString
    $AssetIP = $IPAddress.Split(".")
    $AssetSubnet = ($AssetIP[0]+"."+$AssetIP[1]+"."+$AssetIP[2])
    If ($PrinterSubnet -ne $AssetSubnet){
        Write-Host $ComputerName 'is not on the same subnet as ' $PrinterCaption
        $UserInput = Read-Host 'do wish to install anyway?  Y/N'

        If ($UserInput -eq "Y") {
        } Else {
            Continue
        }
    } Else {
    }
}

现在,当我运行脚本时,我收到以下错误返回

You cannot call a method on a null-valued expression.
At C:\Users\sitblsadm\Desktop\Untitled1.ps1:28 char:1
+ $IPSplit = $PrintIP.Split(".")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Cannot index into a null array.
At C:\Users\sitblsadm\Desktop\Untitled1.ps1:29 char:1
+ $PrinterSubnet = ($IPSPlit[0]+"."+$IPSplit[1]+"."+$IPSplit[2])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

我理解由于$IPSplit未给出值而导致的null数组, 但是我对“你不能在空值表达式上调用方法”的理解是没有为它分配任何东西,但在这个例子中我试图为它赋值。

2 个答案:

答案 0 :(得分:2)

如果Test-Connection返回超时,则$Printer为空。如果名称解析失败(DNS服务器上没有打印机的PTR记录,并且打印机没有响应WINS),IPV4Address为空,因此您在$PrintIP中得到一个空字符串。您可以回退使用Destination字段作为IP地址,或抓取普通$PrinterIP,因为在这种情况下$PrinterIP将包含IP地址。

if ($PrintIP -eq $null) { continue } # can't add unresponsive printer
if ([String]::IsNullOrEmpty($PrintIP.IPV4Address)) {
    $IPSplit = $PrinterIP.Split(".")
} else {
    $IPSplit = $PrintIP.Split(".")
}

您需要学习如何检查空值和位置。并非每个cmdlet都会抛出错误并停止脚本,它们可以返回null并继续,然后您将获得null解除引用异常。

答案 1 :(得分:2)

如果Test-Connection -ComputerName $PrinterIP -Count 1失败,$Printer$PrintIP的值为$null。您需要更多错误处理,使用try-catch-finally块,或检查$?自动变量并抛出错误:

$Printer = Test-Connection -ComputerName $PrinterIP -Count 1
if(-not $?){
    throw "Printer unavailable"
}

Explanation:$?包含上次操作的执行状态。如果上一次操作成功,则包含TRUE;如果失败,则包含FALSE。