PowerShell避免使用脚本范围的变量

DarkLite1

我编写了一个函数来检查主机是否在线或离线,然后返回$true$false此函数运行完美,我想通过查看是否有可能删除脚本范围的变量(如$Script:arrayCanPingResult和)来对其进行一些改进$script:tmpPingCheckServers

我为什么要这个?当我在foreach循环中调用函数时,通常使用开关,-Remember这样它就不会两次检查同一主机。为了能够正确使用此功能,我必须通过将两个变量都声明为空($Script:arrayCanPingResult=$script:tmpPingCheckServers=@{}来开始使用该功能的所有脚本我可以想象人们会忘记在脚本中放入第一行,并且在PowerShell ISE编辑器中进行多次测试时,如果已经在ISE中对主机进行了一次检查(F5),它将不会在第二次运行中再次进行测试。 。

有没有一种方法可以避免在这种情况下使用脚本范围的变量?因此,我们不需要在新脚本的开头将它们声明为空吗?如果可能的话,那就太好了,因为这样我们就可以在自定义模块中包含此功能。

与往常一样,感谢您的建议或帮助。在你们这里​​我真的学到了很多东西。

# Function to check if $Server is online
Function Can-Ping ($Server,[switch]$Remember) {

    $PingResult = {
          # Return $true or $false based on the result from script block $PingCheck
          foreach ($_ in $Script:arrayCanPingResult) { 
                   # Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: $_ " -ForegroundColor Green
                   if ($Server -eq $($_.Split(",")[0])) {

                   #Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: We will return $($_.Split(",")[1])" -ForegroundColor Green
                    return $($_.Split(",")[1])  
                   } 
          }
    }

    $PingCheck = {

        $Error.Clear()

        if (Test-Connection -ComputerName $Server -BufferSize 16 -Count 1 -ErrorAction 0 -quiet) { # ErrorAction 0 doesn't display error information when a ping is unsuccessful

            Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: Ping test ok" -ForegroundColor Gray; $Script:arrayCanPingResult+=@("$Server,$true"); return
        } 
        else {
            $Error.Clear()
            Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: Ping test FAILED" -ForegroundColor Gray

            Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: Flushing DNS" -ForegroundColor Gray
            ipconfig /flushdns | Out-Null

            Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: Registering DNS" -ForegroundColor Gray
            ipconfig /registerdns | Out-Null

            Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: NSLookup" -ForegroundColor Gray
            nslookup $Server | Out-Null # Suppressing error here is not possible unless using '2> $null', but if we do this, we don't get $true or $false for the function so '| Out-Null' is an obligation
            if (!$?) {
                Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: NSlookup can't find the host '$Server', DNS issues or hostname incorrect?" -ForegroundColor Yellow
                # Write-Host $Error -ForegroundColor Red
                if ($SendMail) {
                    Send-Mail $MailTo "FAILED Ping test" "$(Get-TimeStamp) NSlookup can't find the host '$Server', hostname incorrect or DNS issues?" "<font color=`"red`">$error</font>"
                }
                $script:arrayCanPingError += "ERROR | $(Get-TimeStamp) Ping test failed: NSlookup can't find the host '$Server', hostname incorrect or DNS issues?$error"
                $script:HTMLarrayCanPingError += "ERROR | $(Get-TimeStamp) Ping test failed:<br>NSlookup can't find the host '$Server', hostname incorrect or DNS issues?<br><font color=`"red`">$error</font>"
                $Script:arrayCanPingResult+=@("$Server,$false")
                return
                }
            else {
                Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: Re-pinging '$Server'" -ForegroundColor Gray
                if (Test-Connection -ComputerName $Server -BufferSize 16 -Count 1 -ErrorAction 0 -Quiet) {
                   Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: Ping test ok, problem resolved" -ForegroundColor Gray
                   $Script:arrayCanPingResult+=@("$Server,$true")
                   return
                }
                else {
                      Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: DNS Resolving is ok but can't connect, server offline?" -ForegroundColor Yellow
                      if ($SendMail) {
                          Send-Mail $MailTo "FAILED Ping test" "$error" "DNS Resolving is ok but can't connect to $Server, server offline?"
                      } 
                      $script:arrayCanPingError += "ERROR Ping test failed: DNS Resolving is ok but can't connect to $Server, server offline?$error"
                      $script:HTMLarrayCanPingError += "ERROR Ping test failed: DNS Resolving is ok but can't connect to $Server, server offline?<br><font color=`"red`">$error</font>"
                      $Script:arrayCanPingResult+=@("$Server,$false")
                      return
                }
            }
        }
    }

    # Call the script block $PingAction every time, unless the switch $Remember is provided, than we only check each server once
    if ($Remember) {
        Write-Host "$(Get-TimeStamp) $Server > Function Can-Ping: Switch '-Remember' detected" -ForegroundColor Gray
        While ($tmpPingCheckServers -notcontains $Server) { 
                  &$PingCheck
                  $script:tmpPingCheckServers = @($tmpPingCheckServers+$Server) #Script wide variable, otherwise it stays empty when we leave the function / @ is used to store it as an Array (table) instead of a string
        }
        &$PingResult
    } 
    else {
          &$PingCheck
          &$PingResult
    }
}
亚历山大·奥伯斯特

这是我的处理方式:

function Get-PingStatus {
    param(
        # Server object.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        $Server,
        [Parameter(Mandatory=$false)]
        [Bool]$UseLastPingResult = $false
    )

    if ( ($UseLastPingResult) `
    -and (! [String]::IsNullOrEmpty($Server.LastPingResult)) ) {
        # Return unmodified object if LastPingResult property is not empty.
        return $Server 
    }

    try {
        $oPingResult = Test-Connection -ComputerName $Server.Name `
        -BufferSize 16 -Count 1 -ErrorAction Stop

        $Server.LastPingResult = "success"
        # And just in case.
        $Server.IPV4Address = $oPingResult.IPV4Address
    }
    catch {
        $Server.LastPingResult = "failure"
    }

    return $Server
}

反对,反对。通常,这是编写PowerShell函数的最佳方法,因为:1)它与常规cmdlet的功能一致; 2)帮助您使代码简单易读。

与ErrorAction -SilentlyContinue一起使用try ... catch ... finally还是比ErrorAction -SilentlyContinue更好,然后再检查一些变量。

现在,我们假定$ cServerNames是服务器名称或可以解析为IP地址的任何名称的集合。范例:@("server1", "server2", "1.2.3.4", "webserver.example.com")

# Converting strings to objects.
$cServers = @()
foreach ($sServerName in $cServerNames) {
    $oServer = New-Object PSObject -Property @{
        "Name" = $sServerName;
        "IPV4Address" = $null;
        "LastPingResult" = $null;
    }

    $cServers += $oServer
}

# Now we can iterate objects and update their properties as necessary.
foreach ($oServer in $cServers) {
    $oServer = Get-PingStatus -Server $oServer -UseLastPingResult

    if ($oServer.LastPingResult -eq "success") {
        # Do something.
    } else {
        # Do something else like an error message.
    }
}

您可以添加所需的任何诊断输出,但我建议您使用Write-Output和/或Write-Error而不是Write-Host。

最后,请注意,在大多数情况下,ping在生产代码中几乎没有用。这是多余的,并且无论主机是否答复都无法证明。例如,ping可能没问题,但是由于某种原因,您在随后的Get-WmiObject查询中会遇到异常。如果出于性能原因执行ping操作(以节省时间),则应考虑通过后台作业工作流并行运行脚本块

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

通过脚本在环境变量范围内使用PowerShell的灵活性

来自分类Dev

使用powershell从不同脚本调用变量

来自分类Dev

在我的python脚本中使用powershell变量?

来自分类Dev

如何在Powershell脚本传入的SQL脚本中使用变量

来自分类Dev

在Powershell中使用子脚本修改父脚本中的变量

来自分类Dev

Powershell变量范围

来自分类Dev

Powershell变量范围

来自分类Dev

VBS for Excel:在范围选择中使用脚本变量

来自分类Dev

重复脚本遍历变量范围

来自分类Dev

重复脚本遍历变量范围

来自分类Dev

如何使用$ _自动变量调用Powershell脚本块

来自分类Dev

如何在Powershell脚本中使用Jenkins变量

来自分类Dev

在PowerShell脚本中使用秘密变量的正确方法

来自分类Dev

使用环境变量在 VBA 中打开 PowerShell 脚本

来自分类Dev

JCL / MVS脚本变量中是否有避免使用的特殊字符列表

来自分类Dev

JCL / MVS脚本变量中是否有避免使用的特殊字符列表

来自分类Dev

PowerShell脚本中的变量清除

来自分类Dev

PowerShell脚本中的变量清除

来自分类Dev

Powershell脚本如何访问变量

来自分类Dev

PowerShell:Env:避免截断环境变量

来自分类Dev

我如何在从Powershell脚本传入的SQL脚本中使用变量

来自分类Dev

无法从函数内部修改脚本范围的变量

来自分类Dev

无法从函数内部修改脚本范围的变量

来自分类Dev

带有子/父引用的角度/打字稿树-如何避免在声明之前使用块范围的变量

来自分类Dev

如何避免污染当前范围(使用`library(...)`)

来自分类Dev

PowerShell脚本-替换使用

来自分类Dev

PowerShell Winforms Timer 变量范围问题

来自分类Dev

如果未定义变量,请避免运行脚本

来自分类Dev

避免将环境变量传递给python脚本

Related 相关文章

热门标签

归档