adding a timeout to batch/powershell

2019-01-26 12:38发布

$fullnamexp = ((net user $winxp /domain | Select-String "Full Name") -replace "Full Name","").Trim();

If $winxp cannot be found, the command will hang, is there a timeout I can use with this to make it move on after 5-10 seconds? Not sure where I would put it.

Edit- I use this to pull the username:

$reg  = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $tag1)
$key  = $reg.OpenSubKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon')
$winxp = $key.GetValue('DefaultUserName') -replace '^.*?\\'

$winxp is then a login name such as ajstepanik then I put it into: $fullnamexp = ((net user $winxp /domain | Select-String "Full Name") -replace "Full Name","").Trim();

1.21.2014 Update

 $timeoutSeconds = 5
$code = {
    ((net user $winxp /domain | Select-String "Full Name") -replace "Full Name","").Trim(); # your commands here, e.g.
}
$j = Start-Job -ScriptBlock $code
if (Wait-Job $j -Timeout $timeoutSeconds) { $fullnamexp = Receive-Job $j }
Remove-Job -force $j

5条回答
我命由我不由天
2楼-- · 2019-01-26 13:08

This solution doesn't work for me. remove-job -force $j takes over 5 seconds in this example.

$timeoutseconds = 1

$start = get-date
$j = start-job -scriptblock { Resolve-DnsName  1.1.1.1 }
if (wait-job $j -timeout $timeoutseconds) { $fullnamexp = receive-job $j } 
remove-job -force $j 
(get-date) - $start


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 5
Milliseconds      : 342
Ticks             : 53426422
TotalDays         : 6.18361365740741E-05
TotalHours        : 0.00148406727777778
TotalMinutes      : 0.0890440366666667
TotalSeconds      : 5.3426422
TotalMilliseconds : 5342.6422
查看更多
你好瞎i
3楼-- · 2019-01-26 13:10

net doesn't explicitly allow you to set a time out on it's operations, but you could check out this link on changing the ipv4 timeout for your sockets:

http://www.cyberciti.biz/tips/linux-increasing-or-decreasing-tcp-sockets-timeouts.html

The only thing else I could imagine is spawning a worker thread but I don't even know if that's possible in bash, I'm not fluid enough in it to answer that; plus it opens you up to sync problems and all sorts of multi threaded issues beyond what you're trying to accomplish quickly in a bash script to begin with! :P

查看更多
Juvenile、少年°
4楼-- · 2019-01-26 13:12

You can use Start-Sleep to pause the script:

Start-Sleep -s 5
查看更多
我想做一个坏孩纸
5楼-- · 2019-01-26 13:14

While @mjolinor may have indeed provided you an alternative approach, here is a direct answer to your general question: how do you force a timeout in PowerShell?

Wrap whatever you wish to time-limit in a script block, run that as a job, then use the Wait-Job cmdlet to time-limit the operation. Wait-Job will return either at the end of the timeout period or when the script block completes, whichever occurs first. After Wait-Job returns, you can examine the job state ($j.state) to determine whether it was interrupted or not, if it matters to you.

$timeoutSeconds = 5 # set your timeout value here
$j = Start-Job -ScriptBlock {
    # your commands here, e.g.
    Get-Process
    }
"job id = " + $j.id # report the job id as a diagnostic only
Wait-Job $j -Timeout $timeoutSeconds | out-null
if ($j.State -eq "Completed") { "done!" }
elseif ($j.State -eq "Running") { "interrupted" }
else { "???" }
Remove-Job -force $j #cleanup

2014.01.18 Update

Here is a bit more streamlining approach that also includes the practical step of getting information out of the script block with Receive-Job, assuming what you want is generated on stdout:

$timeoutSeconds = 3
$code = {
    # your commands here, e.g.
    Get-ChildItem *.cs | select name
}
$j = Start-Job -ScriptBlock $code
if (Wait-Job $j -Timeout $timeoutSeconds) { Receive-Job $j }
Remove-Job -force $j
查看更多
对你真心纯属浪费
6楼-- · 2019-01-26 13:22

Does this help?

$query = (dsquery user -samid $winxp) 
if ($query) {$fullnamexp = ($query | dsget user -display)[1].trim()}
$fullnamexp
查看更多
登录 后发表回答