Powershell scheduled script is not running properly - powershell

I have a short Powershell script which backup desktop items to D drive
$now = [datetime]::now.ToString('yyyy-MM-dd')
$trigger=new-scheduledtasktrigger -daily -at("08:00am")
$action = new-scheduledtaskaction 'copy "C:\USERS\ADMIN\DESKTOP" "D:\$now" -recurse'
Register-scheduledtask -Action $action -Trigger $trigger -Taskname "dailybackup" -Description "Daily backup"
The code seems valid and scheduled is registered well in scheduler
Get-scheduledtask "dailybackup"
But the task havent executed once but dont know why
anyone knows the solution?

New-ScheduledTaskAction executes commands in the old CMD shell by default. The command you're running doesn't error out because COPY is an ancient CMD built-in. It doesn't actually have the ability to recurse though, so it's not what you want.
To run powershell commands, the task action should execute PowerShell.exe, then have the powershell commands themselves added as arguments like below.
It looks like you want to use the run time date as the folder name $now, so you'll need to re-calculate the date every time it runs,
I also suggest adding -Force to create the target directory as needed,
I'm using here-string formatting #' '# to make quotes and things simpler to handle:
$Action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument #'
-Command Copy-Item -Recurse -Force -Path 'C:\USERS\ADMIN\DESKTOP' -Destination "D:\$([datetime]::Now.ToString('yyyy-MM-dd'))"
'#

Related

Powershell from batch file not working as expected

Let me start with some background. I work in a school district with about 300 laptops using win 10 pro. We are getting ready for our annual standardized testing which uses a lockdown browser. For whatever reason, the company created a new lockdown browser that does not close MSEdge that is running in the background. If you start the lockdown browser as soon as you log in, MSEdge is not an issue.
The provided solution by the software company is to change the registry entries for the test then change it back after the test. That seems like way too much work to me.
My first choice was to use kiosk mode, but it seems it does not work on win 10 pro. The solution I am working on now is to create a user specifically for the testing and use scheduled task at logon with a command to log off at exit. The basic concept seems to work for this situation, as long as the Laptops are plugged in. I can not seem to get the
New-ScheduledTaskSettingsSet –AllowStartIfOnBatteries –DontStopIfGoingOnBatteries
to take effect. I suspect it has to do with the a missing argument, but I can not find any leads with Google searches.
I am using a batch file to call PowerShell and run the .PS1 file
.bat file
:: this Batch file which is run by double clicking in SMACS_IT account. calls powershell to
start the task_kiosk.ps1. Which starts the proccess of creating the scheduled task for the
user STAAR TEST to run TXSecureBrowser.
Powershell.exe -Command "& {Start-Process Powershell.exe -ArgumentList '-ExecutionPolicy
Bypass -File C:\1kiosk\task_kiosk_ps1.ps1' -Verb RunAs}"
.PS1 file
$User = "STAAR TEST"
$Description = "A task created to launch the txsecurebrowser using the kiosk_bat.bat file when
the user STAAR TEST logs in"
$taskName = "Launch TXSecureBrowser"
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName }
$action = New-ScheduledTaskAction -Execute 'C:\1kiosk\kiosk_bat.bat'
$trigger = New-ScheduledTaskTrigger -AtLogOn -User "STAAR TEST"
$settings = New-ScheduledTaskSettingsSet –AllowStartIfOnBatteries –DontStopIfGoingOnBatteries
if($taskExists) {
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
}
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $taskName -Description
$Description -User $User
Set-ScheduledTask -TaskName $taskName -Settings $settings
Using this code I can log in as the test account and the task starts the staar test as long as the laptop is plugged in. The task does not work if laptop is not plugged in. However, If I enter the command manually in PowerShell running as administrator the task will work if the laptop is not plugged in. Which is what leads me to believe that the .bat file needs another argument.
It's been too many years since I worked with Task Scheduler, so I can't help you directly. But, I still have my working script from the time. We needed a webpage updated with a gate counter every couple of minutes and the script below is how I automated the configuring of the scheduled task.
Strip out everything you don't want, insert a few things you do want, and you should pretty much have it.
.CMD file
<# : BATCH Bootstrap for PowerShell
#ECHO OFF
SETLOCAL
PowerShell -executionpolicy remotesigned -Command "Invoke-Command -ScriptBlock ([scriptblock]::Create($([System.IO.File]::ReadAllText('%~f0')))) -ArgumentList ([string]'%*').split()"
ENDLOCAL
GOTO :EOF
#>
# https://blog.netnerds.net/2015/01/create-scheduled-task-or-scheduled-job-to-indefinitely-run-a-powershell-script-every-5-minutes/
# Change these three variables to whatever you want
$jobname = "Gate Count Web Updater"
$script = "C:\Users\Public\GateCountWebUpdater.cmd"
$repeat = (New-TimeSpan -Minutes 2)
# The script below will run as the specified user (you will be prompted for credentials)
# and is set to be elevated to use the highest privileges.
# In addition, the task will run every 5 minutes or however long specified in $repeat.
$action = New-ScheduledTaskAction –Execute $script
$duration = (New-TimeSpan -Days (365 * 20))
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).Date -RepetitionInterval $repeat -RepetitionDuration $duration
$msg = "Enter the username and password that will run the task";
$credential = $Host.UI.PromptForCredential("Task username and password",$msg,"$env:userdomain\$env:username",$env:userdomain)
$username = $credential.UserName
$password = $credential.GetNetworkCredential().Password
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd
Register-ScheduledTask -TaskName $jobname -Action $action -Trigger $trigger -RunLevel Highest -User $username -Password $password -Settings $settings

POWERSHELL Task Scheduler passing variables inside -Argument

Good afternoon,
I am very new to Powershell and am trying to achieve the following:
Loop through a folder directory
Set the folder name as a variable
Create a Task
Pass the variable (declared in Step 2) as the required parameter for the -File being called in the Task Action
Get-ChildItem -Path C:\Users\Paul\Documents\RSYNC -Directory -Recurse |ForEach-Object {
$FolderName = $_.name
$taskName = 'My Powershell Task_' + $FolderName
# Create Action
$Action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-File "C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1" -name "$FolderName"'
# Create Trigger
$Trigger = New-ScheduledTaskTrigger -Daily -At 12:35am
# Create Settings
$Settings = New-ScheduledTaskSettingsSet
# Create Task
$Task = New-ScheduledTask -Action $Action -Trigger $Trigger -Settings $Settings
# Register Task
Register-ScheduledTask -TaskName $taskName -InputObject $Task -User 'username' -Password 'password'
}
The tasks are created as desired, however, the problem is that inside the $Action step, instead of passing the folder name inside the $FolderName variable, it is simply passing $FolderName as a string (I hope that makes sense).
How can I correctly pass the folder name to the PowerShell script being called?
Your immediate problem was to expect the reference to variable $FolderName to be expanded (interpolated) inside a verbatim PowerShell string literal, '...':
Only "..." strings (double-quoted) perform string interpolation in PowerShell: see this answer for an overview of PowerShell's expandable strings (interpolating strings) and this answer for an overview of PowerShell string literals in general.
While swapping the use of quotation marks - using "..." for the outer quoting and '...' for the embedded quoting in order to get interpolation may situationally work - depending on the target program or API - it does not work in the context of Task Scheduler.
For command lines in Task Scheduler - and generally on Windows from outside PowerShell - you must use "..." quoting for the embedded strings too, which therefore requires escaping " as `" ("" would work too).
The reason is that PowerShell doesn't treat ' characters as having syntactic function when its CLI is called from the outside, such as from Task Scheduler, cmd.exe, or the Windows Run dialog (WinKey-R). For instance, if the path passed to -File were 'C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1', the ' chars. would be interpreted as part of the path.
Specifically:
$Action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument `
"-File `"C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1`" -name `"$FolderName`""
Note that you could simplify the quoting with the use of an expandable here-string; the embedded " then do not require escaping:
$Action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument #"
-File "C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1" -name "$FolderName"
"#
Thank you Theo and Abraham Zinala. Both suggested to swap the double and single quotes and that worked perfectly.

Powershell script scheduled task output to log file

I have Powershell script with some Write-Host but I want to use it as scheduled task.
I added it as scheduled task with this:
$action = New-ScheduledTaskAction -Execute "$pshome\powershell.exe -WindowStyle Hidden" -Argument "-File $FilePath"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).Date -RepetitionInterval $repeat
Register-ScheduledTask -TaskName $Name -Trigger $trigger -RunLevel Highest -Action $action
Can I make it write to log file? Is it possible to make it write to file at the same location as the Powershell script?
There were 2 problems with the script and the 1st was my main problem:
if it is not signed default behavior is to be sckipped by the Task Scheduler (or at least I didn't saw an error in the Event Viewer).
I had to use Write-Output
Check if the script is signed with Get-AuthenticodeSignature. Here you are going to receive SignatureStatus as string:
$isSigned = Get-AuthenticodeSignature -FilePath $FilePath | select -ExpandProperty Status
If it is not signed, you can enable the execution of it by adding -ExecutionPolicy Bypass like it is described in this spiceworks how-to. Do this for your own scripts, because of security !
For the writing part I used Write-Output and Out-File:
(
...
Write-Output "some text here"
...
) | Out-File -FilePath "C:\somepath\log.log

PowerShell scheduled task: opens PowerShell and script to be run but doesn't execute script

$Trigger = New-ScheduledTaskTrigger -AtLogOn
$User = "Administrator"
$Action = New-ScheduledTask -Execute "PowerShell_ISE.exe" -Argument "C:\Payload\XML_Read.ps1"
Register-ScheduledTask -TaskName "StartupScript_PS" -Trigger $Trigger -User $User -Action $Action -RunLevel Highest -Force
This is my code which creates a scheduled task and runs fine upon logon. the problem is when it logs on it opens PowerShell and the XML_Read file but I have to manually click run for the XML file to be read etc. Is there a way I can modify my code to do this for me? thanks in anticipation.
You can't execute scripts automatically with the ISE. Instead of PowerShell_ISE.exe, use PowerShell.exe.

Register scheduled task with New-ScheduledTaskTrigger to trigger on event ID

Register-ScheduledTask with New-ScheduledTaskTrigger on a Windows event ID
Hello Stack-overflow users. Neither MSDN nor Google yields results...
I configured a couple of scheduled tasks via a Powershell script. The scheduled tasks are set to run at certain times.
This all works fine. But I need to configure another scheduled task which run when a certain event ID is logged in the Windows event logger.
I can set this up manually of course but I want it as part of my automated script.
this is the code I have so far for the scheduled tasks, I need to replace the $Trigger= New-ScheduledTaskTrigger -At 4:00am -Daily section:
Copy-Item "\\networkDrive\Backups\scripts\Reset-Sessions.ps1" "c:\scripts\Reset-Sessions.ps1"
$Trigger= New-ScheduledTaskTrigger -At 4:00am -Daily
$User= 'Nt Authority\System'
$Action= New-ScheduledTaskAction -Execute "Powershell.exe" -Argument "-executionpolicy bypass -File c:\scripts\Reset-Sessions.ps1"
Register-ScheduledTask -TaskName "Reset-Sessions" -Trigger $Trigger -User $User -Action $Action -RunLevel Highest -Force
I have changed some of the directory and file names for online purposes.
I would appreciate it if somebody could steer me into the right direction or assist with an example.
I would prefer to only change the $Trigger portion and not re-write the whole script but I would understand if it is not possible.
I use Powershell version 5.1.
With this answer as a base and some additional help I was able to construct this script
$taskname="Reset-Sessions"
# delete existing task if it exists
Get-ScheduledTask -TaskName $taskname -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false
# get target script based on current script root
$scriptPath=[System.IO.Path]::Combine($PSScriptRoot, "Reset-Sessions.ps1")
# create list of triggers, and add logon trigger
$triggers = #()
$triggers += New-ScheduledTaskTrigger -AtLogOn
# create TaskEventTrigger, use your own value in Subscription
$CIMTriggerClass = Get-CimClass -ClassName MSFT_TaskEventTrigger -Namespace Root/Microsoft/Windows/TaskScheduler:MSFT_TaskEventTrigger
$trigger = New-CimInstance -CimClass $CIMTriggerClass -ClientOnly
$trigger.Subscription =
#"
<QueryList><Query Id="0" Path="Microsoft-Windows-NetworkProfile/Operational"><Select Path="Microsoft-Windows-NetworkProfile/Operational">*[System[(EventID=4004)]]</Select></Query></QueryList>
"#
$trigger.Enabled = $True
$triggers += $trigger
# create task
$User='Nt Authority\System'
$Action=New-ScheduledTaskAction -Execute "Powershell.exe" -Argument "-ExecutionPolicy bypass -File $scriptPath"
Register-ScheduledTask -TaskName $taskname -Trigger $triggers -User $User -Action $Action -RunLevel Highest -Force
The main magic is to use Get-CimClass to get the correct instance, and then populate Subscription from Get-ScheduledTask "Tmp" | Select -ExpandProperty Triggers
Step1:
Go to eventvwr, then create a new scheduled task based on an eventid.
Step2:
Open powershell, then show the scheduled task and see the the way how to was written.
Step3:
Attached and test it in your scrip.
I created a temporary Get-ScheduledTask and run the below line : all what you have to do is to replace the Subscription to meet your requirement.
$A = (Get-ScheduledTask "Tmp" | select -ExpandProperty Triggers)
Here is another method I used in the end to solve the problem:
If you are trying to do this on a Windows Server prior to Server 2012 then you probably don't have the Get-ScheduledTask and New-ScheduledTaskTrigger and the Register-ScheduledTask modules on your Windows system. That means the script in my original question and the accepted answer won't work.
A workaround is to create the desired scheduled task manually and then export it to a xml file. You can edit this file if you like, it is normal plain text xml.
Then have your script and the xml file in the same directory.
Change your script to be compatible with the older version of Powershell to import the xml file.
schtasks /create /tn "Reset-Sessions" /xml "c:\scripts\Reset-Sessions.xml"
Your new scheduled task should now be registered and active.