【问题标题】:'You cannot call a method on a null-valued expression' Error“您不能在空值表达式上调用方法”错误
【发布时间】:2015-07-09 06:22:17
【问题描述】:

我有一个 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 没有被赋予一个值, 但我对“你不能在空值表达式上调用方法”的理解是没有为它分配任何东西,但在这种情况下,我试图为它分配一个值。

【问题讨论】:

标签: powershell


【解决方案1】:

如果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。

【讨论】:

  • 使用您的建议后,如果打印机无法访问,脚本现在会引发错误。我对脚本进行了更改,因为这似乎不是导致原始错误的原因,现在脚本将用户输入的打印机 IP 直接用于$IPSplit
【解决方案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 取消引用异常。

【讨论】:

    猜你喜欢
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    相关资源
    最近更新 更多