2

I am looking for a command (an IF test) that will run quickly to see if a computer can be connected to. I do one if-test and if it passes then I will run a slew of commands to pull the information I need. If the first test fails, then it does not run the commands as otherwise it would have to fail out on each test which would take a long time.

The following code works, but it is very slow and results in a "GUI (Not Responding)" if the computer is not on the network. I am looking for something to check quicker if it fails.

if (Test-Path "\\$PCNAME\c`$")
{
    # Slew of WMI commands go here.
}

I sometimes query large lists of computers and if a majority of them are off, the command above will take a ton of time to complete.

4

6 回答 6

0

一个更好的解决方案,它使用基于以下的端口测试:https ://theolddogscriptingblog.wordpress.com/2012/05/11/wmi-hangs-and-how-to-avoid-them/

这是那里找到的脚本的修改版本以及使用它的一种方式的示例:

function Test-Port {   
<#
.SYNOPSIS
Tests connection to port 135 on the SQL server, so I guess it is confined to M$ servers 
.DESCRIPTION
.PARAMETER server
computername or IP address
.PARAMETER port
port defaults to 135
.PARAMETER timeout
in milliseconds, defaults to 1000
.EXAMPLE
Test-Port myserver.com
#>
Param(    
    [string] $server,    
    $port=135,    
    $timeout=1000, # milliseconds    
    [switch]$verbose   
 )    
 # Does a TCP connection on specified port (135 by default)    
 # Create TCP Client  https://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient(v=vs.110).aspx  
 $tcpclient = new-Object system.Net.Sockets.TcpClient    
 # Initiate an asynchronous request to machine on Port    
 $iar = $tcpclient.BeginConnect($server,$port,$null,$null)    
 # Set the wait time    
 $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)    
 # Check to see if the connection is done    
 if(!$wait)    
 {    
 # Close the connection and report timeout    
    $tcpclient.Close()    
    if($verbose){Write-Host Connection Timeout  }    
    Return $false   
 }    
 else   
 {    
 # Close the connection and report the error if there is one    
    $error.Clear()    
    $tcpclient.EndConnect($iar) | out-Null   
    if(!$?){if($verbose){write-host $error[0]};$failed = $true}    
    $tcpclient.Close()    
 }    
 # Return $true if connection Establish else $False    
    if($failed){    
    return $false   
    } else {    
    return $true   
    }    
} 
#Found from using for a similar purpose that checking port 49153 was more reliable than 135 
# also the test-connection is unnecessary and that very small timeouts, e.g., 10ms, worked on our network, which really speeds things up but you should test what works on your network
#Use like this
$computername = "myserver.com"
if (Test-Port -srv $computername -port 49153 -timeout 10) {
    # Slew of WMI commands go here.
} else {
    Write-Warning "Could ping $computername but NOT reach RPC port`n so can't use it for WMI"
}
于 2016-04-11T16:37:13.310 回答
0

总结 sdjuan 的答案以快速检查 PCNAME 是否具有 C$ Drive 共享,并允许 WMI 查找:

If ( (Test-Path "\\$PCNAME\c`$") -and (Get-WmiObject win32_bios -ComputerName $PCNAME) ) {
# Slew of WMI commands go here.
}

但是,通过我的测试,CimInstance 查找速度似乎更快,因此:

Get-CimInstance win32_bios -ComputerName $PCNAME

可能会产生更好的结果,但在脚本的其余部分保持一致。

于 2020-11-23T03:28:22.620 回答
-1

您通常会看到 Test-Connection 用于此目的:

if (Test-Connection $PCNAME -Quiet -Count 1)
{
  # Slew of WMI commands go here.
}

编辑:我怀疑如果远程系统支持它,那么使用 CIM 可能会更好。实施细节将取决于远程系统上是否启用了远程处理。

于 2014-12-29T16:42:41.053 回答
-1

有两种简单的方法可以做到这一点:

一种是测试连接:

Test-Connection 192.168.0.2
Test-Connection -CompuetrName "SamsPC"

这可以用作布尔表达式,或与 $? 操作员:

if (Test-Connection 192.168.0.1) {
 do stuff
}

或者

Test-Connection 192.168.0.1
if ($?) {
 Do Stuff
}

另一种方法使用 .NET 类。

$Pinger = New-Object System.Net.NetworkInformation.Ping
$pResult = $Pinger.Send("192.168.0.1")

if ($pResult.Status -eq "Success") {
  Do stuff
}
于 2014-12-29T16:45:45.763 回答
-1

只需对测试连接超时脚本进行一些小的修改,您也可以测试 WMI 功能。只需用 get-wmiobject 调用替换 test-connection 即可获得完整的结果。这是一个修改后的函数:

Function Get-WMI {
param(
    [Parameter(Mandatory = $True)]
    [Object]$computer
)
$timeoutSeconds = 1 # set your timeout value here
$j = Start-Job -ScriptBlock {
    # your commands here, e.g.
    Get-WmiObject win32_bios -ComputerName $args[0]
} -ArgumentList $computer
#"job id = " + $j.id # report the job id as a diagnostic only
Wait-Job $j -Timeout $timeoutSeconds | out-null
if ($j.State -eq "Completed")
{
#connection to PC has been verified and WMI commands can go here.
$Answer = "WMI call WAS SUCCESSFULL to $computer"
}
elseif ($j.State -eq "Running")
{
#After the timeout ($timeoutSeconds) has passed and the test is      
still running, I will assume the computer cannot be connected.
$Answer = "WMI is not running on or could not Connect to $computer"
}
return $Answer
}

我希望这可以帮助别人。

于 2017-08-08T20:21:03.553 回答
-2

我知道这是事后的方式,但我找到了解决方案。我正在寻找一个 if 测试来尝试测试连接,但是当它失败时,失败需要很长时间。建立连接后,它将立即通过。

$timeoutSeconds = 1 # set your timeout value here
$j = Start-Job -ScriptBlock {
    # your commands here, e.g.
    Test-Connection -ComputerName $args[0] -Count 1
} -ArgumentList $computer
#"job id = " + $j.id # report the job id as a diagnostic only
Wait-Job $j -Timeout $timeoutSeconds | out-null
if ($j.State -eq "Completed")
{
    #connection to PC has been verified and WMI commands can go here.
    $richtextbox1.Text = "Connection can be made to $computer"
}
elseif ($j.State -eq "Running")
{
    #After the timeout ($timeoutSeconds) has passed and the test is still running, I will assume the computer cannot be connected.
    $richtextbox1.Text = "Could not Connect to $computer"
}

我不确定我从哪里得到这个代码。我想我用过 -为批处理/powershell添加超时

我希望这对将来的某人有所帮助。

于 2015-03-03T17:53:22.133 回答