问题
I have been stuck on this for last day or so and I think its something small that I just can't see.
To summarize the code: Powershell script that will run every 60 seconds to take a screen capture. On Windows Server 2012 this works perfectly fine. While on Windows 7, only first screen shot is taken and then all after are "blank" with just white space the size of dimensions. Any Ideas why this happens?
I also attempted to remove the bigger while loop and do a scheduled task that runs every 5 minutes, but again that doesn't work and all I get is a blank white image. Any thoughts? On windows 7. I am using local Admin user.
I am using powershell 4 across both windows 7 and windows server 2012. And .Net 4.5
while($true){
[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
function screenshot([Drawing.Rectangle]$bounds, $path) {
$bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
$graphics = [Drawing.Graphics]::FromImage($bmp)
$graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
$bmp.Save($path)
$graphics.Dispose()
$bmp.Dispose()
}
#NUC bounds
$bounds = [Drawing.Rectangle]::FromLTRB(0, -1080, 1920, 1080)
#remote display bounds
#$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, 1280, 800)
$PC_name=$(Get-WmiObject Win32_Computersystem).name
$dateandtime = Get-Date -Format yyyy-MM-dd-hh-mm-ss
$path_pcname= "C:\Scripts\Screenshots\" + $PC_name + "_screenshot_" + "$dateandtime"+ ".png"
screenshot $bounds $path_pcname
$limit = (Get-Date).AddMinutes(-15)
$path_todelete = "C:\Scripts\Screenshots\"
# Delete files older than the $limit.
Get-ChildItem -Path $path_todelete -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
Start-Sleep -Seconds 60
}
Edit: I realized that this line: [Reflection.Assembly]::LoadWithPartialName("System.Drawing") which reads from the GAC, isn't being initiated correctly. Not sure if this helps.
回答1:
Cool script.
The only modification I made to get it working working, on both Windows 2012R2 and Windows 7 Enterprise with SP 1 and also both running PowerShell 4, is the bounds variable:
$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, 1600, 900) # My resolution.
Works great.
Now, just trying to think of a purpose for it.
Thanks for sharing your script.
回答2:
When the task is run from an alternate context than the logged-in user (any user, if the system is a terminal), it does not have access to the desktop, that's why you get empty screenshots. The script works, except that I've moved all the code that does loading, presetting and declaring a function out from the loop, and has managed to run it as a scheduled task with correctly formed screenshots. This behavior is by default, and is a security concern, because other users should not have access to the desktop of a current user, local system included. You can place such a task in the task manager to run under a specific user, but you'll be prompted for that user's password to store the task in the Task Scheduler. After you create the task, you'll be able to set its schedule and set it to be run only when the user is logged in (an interactive task). If so, hide Powershell window by using -WindowStyle hidden
in powershell.exe
parameters.
In short, this can only create correct screenshots if run from under the logged in user. Scheduled tasks qualify if users match. Running as system or local admin won't allow you to get screenshots.
来源:https://stackoverflow.com/questions/27770010/powershell-screen-capture