Zabbix script timeout - powershell

I'm trying to run powershell script for cleaning disk on agent from Zabbix. Seems that script is running too long and instead response I got error.
powershell -NonInteractive C:\Scripts\CleanDisk.ps1 -deleteLogsOlderThanDays 10
Script deletes some logs and temp folders and prints statistics. If there is only few folders to delete it work fines. But if script runs too long then dialog windows with script result ends with error Get value from agent failed: ZBX_TCP_READ
Guess that it's because connection to client timeout. Is there some way how to get over this limitation?
Thx

My colleagues found usable workaround. Instead of starting script which will run long time it's better to only schedule script with schtask.exe. So I modified script, now it contains two parts. One is responsible for scheduling and starting scheduled task (schedule it self but with different arguments), second heavy and long running does the action. Result of scheduling will appear in execution script dialog box in zabbix, result of long running action is going to log file...
Here is example of powershell script StartCleanDisk.ps1. In this case task will be scheduled and immediately executed by scheduler.
StartCleanDisk.ps1 -deleteLogsOlderThanDays 10 -startAsTask 1
In this case task will directly executed.
StartCleanDisk.ps1 -deleteLogsOlderThanDays 10 -startAsTask 0
StartCleanDisk.ps1 content:
[CmdletBinding()]
param
(
[parameter(Mandatory=$true)]
[int]
$deleteLogsOlderThanDays,
[bool]
$startAsTask = $false
)
if ($startAsTask)
{
Write-Output "Scheduling task for cleaning disk ...";
$taskname = "CleanDisk"
$logFile = "X:\logs\Tasks\cleaningDisk.log";
$task = "powershell $PSScriptRoot\StartCleanDisk.ps1 -deleteLogsOlderThanDays $deleteLogsOlderThanDays -startAsTask 0 > $logFile 2>&1";
& schtasks /create /ru "System" /tn $taskname /tr $task /sc once /ST 23:59 /F /V1 /Z;
Write-Output "Task Clean disk created...";
& schtasks /run /tn $taskname;
Write-Output "Task $taskname started... Please chek $logFile";
exit 0;
}
#####################
# Script begins here
# PUT HERE COMMANDS FOR DELETING
#####################

Start as a hidden process
UserParameter=Key[*],powershell -NoProfile -ExecutionPolicy Bypass Start-Process powershell -ArgumentList \\Path\SYSVOL\..\scripts\Files\Zabbix\Key.$1.ps1 "$2" "$3" -Windowstyle Hidden
Where Key[*] is an active item in Zabbix agent for start powershell at windows host,
$1 for variation of name PowerShell scrips, "$2" "$3" "next" for any parameters
if $1="Ring" then the name of the script will Key.Ring.ps1

Related

Windows scheduler not executing task

The below command-line will successfully execute a powershell command invisibly; saving the output to a text file:
C:\Windows\System32\wscript.exe C:\temp\invisible.vbs C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -WindowStyle Hidden -command ( (Get-StartApps -Name 'RDP (Tools)').AppID > c:\Temp\AppB.txt )
invisible.vbs:
CreateObject("Wscript.Shell").Run "" & WScript.Arguments(0) & "", 0, False
However, if I create a Windows scheduler task where the Action is: EXE = C:\Windows\System32\wscript.exe and...
ARGUMENTS = C:\temp\invisible.vbs C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -WindowStyle Hidden -command ( (Get-StartApps -Name 'RDP (Tools)').AppID > c:\Temp\AppB.txt )
...the text file doesn't get created when I run the scheduler task; even though it says operation completed successfully (0x0).
How can I create a Windows scheduler task that does the same thing as from a command line?
HINT: When I run the scheduled task, a powershell.exe process is spawned by Task Scheduler. However, it doesn't appear to be doing anything. Something is causing the PowerShell process to not run as expected. Unfortunately, I can't tell what's happening.
HINT2: When I completely eliminate the VBScript; where Task Schedule executes only PowerShell; and, the respective command, it works fine. Unfortunately, I don't know vbscript well enough to know why this isn't working.
MKNANET,
FWIW: I had no problem running w/o the VBS as follows:
Task Scheduler--
Command: "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
Arguments: -noprofile -WindowStyle Hidden -command (Get-StartApps -Name "*Office*").AppID >> G:\Test\AppB.txt
Note: as I didn't have any 'RDP (Tools)' items in my app list I changed it to look for Office items.
HTH

Need to run two actions inside a scheduled task. Need one to run after the first finishes

I have powershell code to create a task that "ghosts" a harddrive using ghost.exe. I need to create a single task that first runs ghost.exe with all my parameters, then after it is finished, runs the next action that will verify the image using a powershell script.
The trick is telling the task to wait until the backup is created, then run the verify. In my attempts, it starts the backup then immediately tries to verify. How can I do this?
Line:
cmd /c schtasks /Create /RU 'SYSTEM' /SC once /TN hotghost /SD $startdate
/ST $starttime /TR $hotghosttask
/TR is "task to run" but I cannot add another /TR to add another action.
If it's an existing item that you're waiting on a change for and your roughly know how long the "ghost" usually takes, a simple solution would be to just build a control in the PowerShell-script that will be run afterwards, to wait for a new LastWriteTime on the image. In the below example, when the $temp.LastWriteTime matches the current month, day, year and hour, the script will continue.
See the below example:
$Date = Get-Date -Format "MM-dd-yyyy hh:"
do {
$temp = Get-Item C:\temp\temp.txt
}
until($temp.LastWriteTime.ToString("MM-dd-yyyy hh:") -eq $date)
Write-Host "Starting image verification..."
[your code begins here]
Another alternative would be to create a temp-file that's generated after the first task has been completed and just use a do/until loop until the statement is true.
do {
$temp = Test-Path C:\temp\temp.txt
}
until($temp -eq $true)

Windows Task for restart if user not logged in

I'm trying to create scheduled task for Windows reboot, which is executed if any user is not logged in. If user is logged in locally or over RDP, the machine should not be restarted.
For unconditional restart, I have task in Task Scheduler with:
Action: "Start a program", Program/script: "powershell", Add arguments: "restart-computer -force"
For conditional restart I have powershell code:
$ErrorActionPreference = "Continue"
$userstatus = quser /server:'localhost'
if(!$userstatus){
Restart-Computer -Force
}
else{
exit
}
I can get the conditional restart working fine when I save the script as .ps1 file and add the filepath to the schedule as argument. I need the conditional restart with several desktops and I would like to avoid saving the .ps1 file locally for each machine. Is it possible to pass the entire script as argument?
Your logic's a bit off. If you plan on creating the scheduled task for each PC, it should look something like this:
$Users = quser.exe
If ($Users -match 'No\sUser') { Restart-Computer -Force }
From here, because of the syntax, you should encode it, then you could utilize schtasks.exe to create your task:
[Convert]::ToBase64String(
[Text.Encoding]::Unicode.GetBytes(
"If(#(quser.exe) -match 'no\suser'){Restart-Computer -Force}"
)
)
Output:
SQBmACAAKABAACgAcQB1AHMAZQByAC4AZQB4AGUAKQAgAC0AbQBhAHQAYwBoACAAJwBuAG8AXABzAHUAcwBlAHIAJwApAHsAUgBlAHMAdABhAHIAdAAtAEMAbwBtAHAAdQB0AGUAcgAgAC0ARgBvAHIAYwBlAH0A
schtasks.exe /Create /TN AutoRestart /SC DAILY /ST 20:00 /RU SYSTEM /TR "powershell.exe -EncodedCommand SQBmACAAKABAACgAcQB1AHMAZQByAC4AZQB4AGUAKQAgAC0AbQBhAHQAYwBoACAAJwBuAG8AXABzAHUAcwBlAHIAJwApAHsAUgBlAHMAdABhAHIAdAAtAEMAbwBtAHAAdQB0AGUAcgAgAC0ARgBvAHIAYwBlAH0A"

2 url's in powershell with cmd

I have create the following schedule task but I would like to add a second url which will run after the end of the first. Could anyone help με how can I do it??
Thanks in advance.
schtasks /create /tn "My Task Title" /tr "powershell -ExecutionPolicy unrestricted -Command \"(New-Object Net.WebClient).DownloadString(\\\"Url1\\\")\"" /sc DAILY /ru username /rp pass
If you have multiple URLs it would be best to move some of the logic into a PowerShell script file to push some of the logic away from the command line. Not that you could put this all in the command line but for ease and readability using the -File parameter of powershell would be a better way to go. First you would need to create a file called "Get-WebStrings.ps1" with the following contents.
# Check to be sure we have at least one argument.
If($args.Count -gt 0){
# Treat each argument as a URL that we need to download.
ForEach($singleURL in $args){
# Download the string
(New-Object Net.WebClient).DownloadString($singleURL)
# Optional depending on your needs
# (New-Object Net.WebClient).DownloadString($singleURL) | Out-Null
}
}
What this script will do it take the arguments sent to it as treat each one as a url and download the data. By default this would output to console. If merely performing the download is all you wish then you could pipe the output into Out-Null (see commented code above).
Next you would need to create the task in the command line much like you have already done. Note that this file needs to be accessible on the local system where the task is being called! Each URL is placed inside single quotes in the string.
schtasks /create /tn "My Task Title" /tr "powershell -ExecutionPolicy unrestricted -File 'C:\Temp\Get-WebStrings.ps1' 'https://www.google.com' 'http://www.purple.com'" /sc daily /ru username /rp pass
If you were to look at the Action inside Task Scheduler it would look like this after that was run.
-ExecutionPolicy unrestricted -File "C:\Temp\Get-WebStrings.ps1" "https:\\www.google.com" "https:\\employee.firstair.ca"

Windows powershell script triggered by PSExec is not killing Powershell process when it finishes running

I need to complete a series of tasks across several Windows 2008 servers that need elevated permissions and as such I've had to create a series of scheduled tasks that i'm running via psexec. Since they have to run in sequence, I found and modified a powershell script that 'stalls' until scheduled tasks are completed on remote machines. The problem I have is that when I launch the script with psexec on the remote machine, once it completes running (indicated by a message in the console output) PowerShell.exe doesn't exit cleanly, but rather hangs out and holds up the entire process. I need powershell to quit after the delay script exits, but even with an exit keyword at the end it stays in memory and prevents the process from finishing. I'm not terribly experienced with powershell so I'll attach my script in case I'm doing something foolish in it:
while($true) {
$status = schtasks /query /tn "AutoDeploy"| select-string -patt "AutoDeploy"
if($status.tostring().substring(64,7) -eq "Running") { "Waiting for task to complete..." } else { break }
start-sleep -s 5
}
"Task complete."
exit
Thanks in advance for any insight.
This works for me (using a different task name) and doesn't hang psexec:
$taskName = "AutoDeploy"
while (1)
{
$stat = schtasks /query /tn $taskName |
Select-String "$taskName.*?\s(\w+)\s*$" |
Foreach {$_.Matches[0].Groups[1].value}
if ($stat -ne 'Running')
{
"Task completed"
break
}
"Waiting for task to complete"
Start-Sleep 5
}