Long Running Powershell Script Freezes
We are using a long running PowerShell script to perform开发者_如何学C a lot of small operations that can take an extremely long amount of time. After about 30 minutes the scripts froze. We were able to get the scripts to start running again by pressing Ctrl-C
which caused the scripts to resume execution instead of killing the process.
Is there some sort of script timeout or mechanism that prevents long running scripts within PowerShell?
I had this problem due to a bad habit I have. If you select a little bit of text inside a console powershell, scripts logs freeze. Make sure nothing is selected after launching a big script :)
Like mentioned, when clicking/selecting text in powershell console, the script stops. You can disable this behaviour like this:
Right-click the title bar
Select
Properties
Select
Options
Under
Edit Options
, disableQuickEdit Mode
Note: You won't be able to select text from powershell window anymore.
Try my kill timer script. Just change the $ScriptLocation
variable to the script you want to run. That script will then run as a background job while the current windows keeps track of the timer. After the time expires the current window will kill the background job and write it all to logs.
Start-Transcript C:\Transcriptlog-Cleanup.txt #write log to this location
$p = Get-Process -Id $pid | select -Expand id # -Expand selects the string from the object id out of the current process.
Write-Host $p
$BJName = "Clean-up-script" #Define Background job name
$startTime = (Get-Date) # set start time
$startTime
$expiration = (Get-Date).AddMinutes(2)#program expires at this time
# you could change the expiration time by changing (Get-Date).AddSeconds(20) to (Get-Date).AddMinutes(10)or to hours or whatever you like
#-----------------
#Timer update function setup
function UpdateTime
{
$LeftMinutes = ($expiration) - (Get-Date) | Select -Expand minutes # sets minutes left to left time
$LeftSeconds = ($expiration) - (Get-Date) | Select -Expand seconds # sets seconds left to left time
#Write time to console
Write-Host "------------------------------------------------------------------"
Write-Host "Timer started at : " $startTime
Write-Host "Current time : " (Get-Date)
Write-Host "Timer ends at : " $expiration
Write-Host "Time on expire timer : " $LeftMinutes "Minutes" $LeftSeconds "Seconds"
Write-Host "------------------------------------------------------------------"
}
#get background job info and remove the it afterwards + print info
function BJManager
{
Receive-Job -Name $BJName #recive background job results
Remove-Job -Name $BJName -Force #remove job
Write-Host "Retrieving Background-Job info and Removing Job..."
}
#-----------------
$ScriptLocation = "C:\\Local-scripts\Windows-Server-CleanUp-Script-V2.4(Beta).ps1" #change this Var for different kind of script locations
Start-Job -Name $BJName -FilePath $ScriptLocation #start this script as background job
# dont start job in the loop.
do{ #start loop
Write-Host "Working"#start doing other script stuff
Start-Sleep -Milliseconds 5000 #add delay to reduce spam and processing power
UpdateTime #call upadate function to print time
Get-Job -Name $BJName | select Id, State ,Location , Name
if((Get-Job).State -eq "Failed")
{
BJManager
}
elseif((Get-Job).State -eq "Completed")
{
BJManager
}
}
until ($p.HasExited -or (Get-Date) -gt $expiration) #check exit time
Write-Host "Timer Script Finished"
Get-Job -Name $BJName | select Id, State ,Location , Name
UpdateTime
BJManager
Start-Sleep -Milliseconds 5000 #give it some time to write to log
Stop-Transcript
Start-Sleep -Milliseconds 5000 #give it some time to stop the logging before killing process
if (-not $p.HasExited) { Stop-Process -ID $p -PassThru } # kill process after time expires
try to add percentage calculation in your script.. so you can identity that how much time it would take to complete...
精彩评论