I have to download a file from an SFTP server everyday. I have the program which retrieves the file from the server but I was thinking of setting up a cron job (or anything similar) to automate that. We are a Windows shop and need to set up the cron job in Windows.
The windows equivalent to a cron job is a scheduled task.
A scheduled task can be created as described by Alex and Rudu, but it can also be done command line with schtasks (if you for instance need to script it or add it to version control).
An example:
schtasks /create /tn calculate /tr calc /sc weekly /d MON /st 06:05 /ru "System"
Creates the task calculate, which starts the calculator(calc) every monday at 6:05 (should you ever need that.)
All available commands can be found here: http://technet.microsoft.com/en-us/library/cc772785%28WS.10%29.aspx
It works on windows server 2008 as well as windows server 2003.
Make sure you logged on as an administrator or you have the same access as an administrator.
Start->Control Panel->System and Security->Administrative Tools->Task Scheduler
Action->Create Basic Task->Type a name and Click Next
Follow through the wizard.
There's pycron which I really as a Cron implementation for windows, but there's also the built in scheduler which should work just fine for what you need (Control Panel -> Scheduled Tasks -> Add Scheduled Task).
http://windows.microsoft.com/en-US/windows7/schedule-a-task
maybe that will help with windows scheduled tasks ...
If you don't want to use Scheduled Tasks you can use the Windows Subsystem for Linux which will allow you to use cron jobs like on Linux.
To make sure cron is actually running you can type service cron status from within the Linux terminal. If it isn't currently running then type service cron start and you should be good to go.
I would like to thank #Vincent Stevenson, #s-hunter
Go to Control Panel --> Administrative Tools --> Task Scheduler--> Create Task
Task Scheduler, Create Task
Give the Task a title
Go to Actions
Go to CMD to find the path,
Python, import sys, sys.executable
(this tells you what the Program/script field should be populated with: "some path
with Appdata mostly")
like:C:\Users\admin\AppData\Local\Programs\Python\Python38-32\python.exe
Arguments: name of the python script (like run.py)
Start in: dir location of python script (like:C:\Users\admin\Documents\my_python_project)
Go to Triggers, schedule as you like
Test the script by running it
There are also cmdlets in powershell for this:
https://learn.microsoft.com/en-us/powershell/module/scheduledtasks/new-scheduledtask?view=windowsserver2022-ps#example-2-define-a-scheduled-task-with-multiple-actions
The linked example:
PS C:\> $actions = (New-ScheduledTaskAction -Execute 'foo.ps1'), (New-ScheduledTaskAction -Execute 'bar.ps1')
PS C:\> $trigger = New-ScheduledTaskTrigger -Daily -At '9:15 AM'
PS C:\> $principal = New-ScheduledTaskPrincipal -UserId 'DOMAIN\user' -RunLevel Highest
PS C:\> $settings = New-ScheduledTaskSettingsSet -RunOnlyIfNetworkAvailable -WakeToRun
PS C:\> $task = New-ScheduledTask -Action $actions -Principal $principal -Trigger $trigger -Settings $settings
PS C:\> Register-ScheduledTask 'baz' -InputObject $task
Related
I am trying to build an AWS AMI for a gitlab runner for building our .NET application.
I am using packer for building the image based one the official Windows Server 2019 base AWS AMI.
I am using WinRM, with HTTPS, not changing any password.
Here are the powershell commands to configure the virtual machine :
"Creating desktop directory"
mkdir C:\Windows\SysWOW64\config\systemprofile\Desktop
"Installing ntrights tools"
mkdir tools
Invoke-WebRequest -Uri "https://download.microsoft.com/download/8/e/c/8ec3a7d8-05b4-440a-a71e-ca3ee25fe057/rktools.exe" -OutFile "tools\tools.exe" -UseBasicParsing
Start-Process "tools\tools.exe" -ArgumentList "/T:$pwd\tools\ /C" -Wait
Start-Process "msiexec.exe" -ArgumentList "/i $pwd\tools\rktools.msi /qn" -Wait
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
Remove-Item tools -Recurse
"Setting rights of service logon to $Env:WINRMUSER"
ntrights.exe ntrights +r SeServiceLogonRight -u $Env:WINRMUSER
# Git lab runner
$path = ".\gitlab-runner.exe"
If(!(test-path $path))
{
"Downloading Gitlab Runner"
Invoke-WebRequest -Uri "https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-windows-386.exe" -OutFile $path -UseBasicParsing
}
"Scheduling runner to start at startup of the system"
schtasks.exe /create /tn "Gitlab Runner service start" /RU $Env:WINRMUSER /RP `"$Env:WINRMPASS`" /Sc ONSTART /tr "powershell -Command $pwd\register-gitlabrunner.ps1 -ExecutionPolicy Bypass"
There are obviously more scripts executed (install msbuild, install .net sdk 4.7.2, nugget, and git) I can provide them if relevant. Here I focus on the powershell code I came up with for the gitlab runner problem.
I want the virtual machine to start the runner on start so we just have to launch instances of the AMI to scale up.
To explain a bit more what I did try :
You can see I am trying to create the desktop directory in order for windows to get that it can run interactive things... Not working
I am setting up the SeServiceLogonRight in order to avoid the "failed to logon" error
The user is Administrator, and the password is the right password
The scheduled tasks is created and ready to run. Won't run on start, won't run If i start it through schtasks /Run (the last run time is never updated and show a value in 19XX)
Tried to cmd /c the task command, everything work as expected
I don't find any logs anywhere, event log seems to be empty of problem from Application, System and Powershell. The file in c:\Windows\Tasks\SchlogU (or something like that), does not exist (but the folder exists)
I have no UI for the scheduler, I use a light version of windows so all I can do is play with the schtasks.exe
Default folder is : c:\Users\Administrator
The powershell script is pushed by packer onto the server and is located in c:\Users\Administrator (as for the gitlab-runner.exe)
I connect directly through RDP to try debugging the situation.
Here is the script that should be started
Set-Location $PSScriptRoot
$path = ".\gitlab-runner.exe"
"Stopping runner"
Invoke-Expression "$path stop"
"Unregistering previous configuration"
Invoke-Expression "$path unregister --all-runners"
"Uninstalling runner"
Invoke-Expression "$path uninstall"
"Installing runner"
Invoke-Expression "$path install"
"Registering Gitlab Runner"
Invoke-Expression "$path register --non-interactive --url 'https://URL_HERE/' --registration-token 'TOKEN HERE' --executor shell"
"Starting the runner"
Invoke-Expression "$path start"
I can install the runner only once in the configuration using the user and password but this is not the problem here since the task never runs...
Answer the question with what I came up thanks :
I was told by so many docs and answers everywhere that the task scheduler is the way to go when you need to start scripts at startup or logon.
As I always worked with windows servers with GUIs, the Task Scheduler was working fine until now. Maybe I did something wrong somewhere, maybe not.
Anyway, after trying using powershell commands to create the task (with improvements but no sufficient solutions), I tried to put a command file in the C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp, did not work either.
the file look like this thanks to this link
PowerShell -Command "Set-ExecutionPolicy Unrestricted"
PowerShell -Command "c:\Users\Administrator\register-gitlabrunner.ps1" >> c:\startup.log.txt
I tried to delay the start of the script to 5 minutes after startup. Was to test if it was a problem with a slow initialization of network or something else. Still not working.
There is something preventing the script to be executed when it's launched at startup using this methods.
From there I added a persistent "user_data" script on my EC2 launch template in order to start what I was expecting on start. It works.
I don't feel it's the best way since I need to configure the template and not only the AMI but at least it works.
The script in user_data looks like this :
<script>
cmd /c "C:/ProgramData/Microsoft/Windows/Start Menu/Programs/StartUp/startup.cmd"
</script>
<persist>true</persist>
I kept the installation and registering in the startup script since I got logon errors when I install gitlab runner through WinRM using the account credentials (--user --password)
I still don't understand what is up with this issue. I guess it's a problem with the account used to start the script (localsystem or something like that, that would conflict with the gitlab runner service).
Since I have no GUI (the docs are mostly on GUI) and limited time, I won't investigate more for the moment and feel it's enough at least for the moment.
Hope this can help someone that will encounter the same situation
I use a script to create a windows scheduled task to call a powershell script in elevated mode to run windows update by using boxstarter (a tool could automatically continue running code even there is reboot during the execution) when system startup. But not sure why, the task could be called after startup, but nothing has been done. If I manually start the scheduled task in task manager, it will run as expected.
Script to register a scheduled task:
$TaskActionArgument ="-noprofile -command "&{start-process powershell -argumentList '-File C:\users\administrator\updatescript\boxstarter.ps1 -verb runas'}""
$TaskAction = New-ScheduledTaskAction -Execute "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" -argument $TaskActionArgument
$TaskTrigger = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -TaskName boxstarter -Action $TaskAction -Trigger $TaskTrigger -User administrator -Password Vmc12svt -RunLevel Highest
I checked the event log viewer and see following error message for the scheduled job:
System
Provider
[ Name] PowerShell
EventID 403
[ Qualifiers] 0
Level 4
Task 4
Keywords 0x80000000000000
TimeCreated
[ SystemTime] 2018-01-10T18:21:12.000000000Z
EventRecordID 267
Channel Windows PowerShell
Computer WIN-6HSHKOKP31E
Security
EventData
Stopped Available NewEngineState=Stopped
PreviousEngineState=Available SequenceNumber=16 HostName=ConsoleHost
HostVersion=4.0 HostId=13ece112-b027-4051-9ddf-1a195d3aa30f
HostApplication=C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-File C:\users\administrator\updatescript\boxstarter.ps1 -verb runas EngineVersion=4.0 RunspaceId=d158a216-18e3-4e86-9ade-b232201c9cdc
PipelineId= CommandName= CommandType= ScriptName= CommandPath=
CommandLine=
For the error message, I googled and found explain of error code here
In general, the page says such issue could be caused by following error:
The Task Scheduler service is disabled
The COM service is disabled
The Windows Event Log service is disabled
The RPC service is disabled
There is not enough free memory
Non of above is true for my system.
So what's error with my scheduled task? How could I make it work?
It looks like all your services are not setup. It's a common problem on things that run on startup/login. There's a -RandomDelay parameter to New-ScheduledTaskTrigger. I recommend you tinker with that if its your own machine you are testing this with. My example uses 1 minute.
$TaskTrigger = New-ScheduledTaskTrigger -AtStartup -Delay (New-TimeSpan -Minutes 1)
If you want a minute or so, all the services needed should be started up by then.
Another thing you'll want to do is have the your code in a try/catch, so the error is being written out to a log file, so you can see the error in the context of PowerShell, which might provide a more detailed message than what you are getting in the event log.
You can troubleshoot this by creating the scheduled task manually and then trying to run it.
Try changing the TaskActionArgument property to only the following string:
-NoProfile -ExecutionPolicy Bypass -File C:\users\administrator\updatescript\boxstarter.ps1
You don't need Start-Process or -Verb runas. In fact, -Verb runas will actually keep things from working, because it provokes a UAC prompt, which you don't want when trying to automate.
Created one Windows Scheduled Task in Remote Server, task action is logoff the user and this task will trigger when specific user had logged in. Here by mistakenly I had selected any user instead of specific user. Now how can I delete/disable that scheduled task on Remote windows server using my windows machine.
You can employ Get-ScheduledTask, Disable-ScheduledTask and Unregister-ScheduledTask to retrieve, disable and delete scheduled tasks. These work on the local PC by default, but you can employ Powershell remoting to run these cmdlets on a remote computer. You can also use -CimSession parameter to retrieve data from remote computer.
Schtasks.exe also has /query parameter and can return all the tasks from a remote computer, so you can then use schtasks /delete as said in comments.
Try this code:
$servers = get-content ".\serverslist.txt"
foreach ($server in $servers)
{
Unregister-ScheduledTask -CimSession $server -TaskName "TaskName" -Confirm:$false
}
I am trying to have a power shell script resume after a reboot. (I am rebooting to "apply" registry changes I have made") I believe I can accomplish what I want by making a registry edit to the Run Once key. I have looked at this question, but I can't get my similar code to execute at boot. The registry edit is made and at boot something runs because it disappears but it is not finishing the install.
$part2 = Get-ChildItem C:\Windows\ccmcache\ -Recurse -Force -Filter Full_Druva_Reinstall_part2.ps1
$FullPath = $part2.FullName
$KeyPath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
new-itemproperty -Path $KeyPath -Name !Install-Druva -propertytype String -value "Powershell -executionPolicy Unrestricted -File $FullPath"
Edit
This scrpit is inside a SCCM Package and any solution needs to automatic and require no user input.
Open task scheduler on general give a name> run wheter user logged in or not> trigger at startup>
action
program/script will be powershell.exe
arguments
-ExecutionPolicy Bypass -File "C:\myscripts.ps1"
I wasn't able to make the Run Once Registry work, plus it wouldn't tun with admin cred if a non admin logged in. I also wasn't able to make a schedule task in power shell because my environment is all Win7 and power shell v4.
The solution i used was making a task sequence in SCCM that ran part 1 of my script, restarted, and then ran part 2.
For simplicity, let's say the user Administrator is logged in in terminal session 2. Another user Boda is logged in terminal session 3.
Is it possible to runas a program in session 3 from session 2?
For simplicity, let's say I want to start calc.exe in session 3 (in Boda's session). How do I do that? Can it be done with runas?
Like Harry Johnston suggested in a comment you can do this using the psexec tool available on TechNet. I've tried it using a Windows 2008 Server running Terminal Services and managed to start various applications in another users session (although not calc.exe - it started but minimized and the window refused to restore), among them cmd.exe.
The command I used was psexec.exe -i 3 cmd.exe where 3 is the session number (that you can get from qwinsta.exe).
Example: Remote session, logged on as Administrator; using qwinsta to enumerate sessions and psexec to start cmd.exe on another session.
Another session: logged on as Patrick, with the cmd.exe window on the desktop opened by Administrator (which the window title reveals too).
There is a commandline tool and it’s called RunInSession. You need to specify at least the SessionId in which you want to launch the process and which process you want to launch. Optional is servername if you want to launch on a remote server. If you run it without parameters a dialog with possible parameters is shown:
Currently supported OS versions are Windows XP, 2003, Vista and 2008.
The program needs to run in the context of the Localsystem user, therefore it temporarily installs itself as service and start itself. With the WTSQueryUserToken it obtains the Primary User token of the requested Terminal Session. Finally the process is launched with CreateProcessAsUser and the service deletes itself.
More details:
How to launch a process in a Terminal Session
Launching an interactive process from Windows Service in Windows Vista and later
Its kind of an hack, but its very useful to me. Way more faster than psexec.exe in my environment.
Just create a temporary task in a remote computer, for a specific user or group, run it, than delete the task.
I created a powershell script for it:
param (
[string]$Computer = ($env:computername),
[string]$User = "",
[string]$Command,
[string]$Args
)
$script_task =
{
param (
[string]$User = "",
[string]$Command,
[string]$Args
)
#Action
$Action = New-ScheduledTaskAction –Execute $Command
if($Args.Length > 0) { $Action = New-ScheduledTaskAction –Execute $Command -Argument $Args}
#Principal
$P = New-ScheduledTaskPrincipal -UserId $User -LogonType Interactive -ErrorAction Ignore
#Settings
$S = New-ScheduledTaskSettingsSet -MultipleInstances Parallel -Hidden
#Create TEMPTASK
$TASK = New-ScheduledTask -Action $Action -Settings $S -Principal $P
#Unregister old TEMPTASK
Unregister-ScheduledTask -TaskName 'TEMPTASK' -ErrorAction Ignore -Confirm:$false
#Register TEMPTASK
Register-ScheduledTask -InputObject $TASK -TaskPath '\KD\' -TaskName 'TEMPTASK'
#Execute TEMPTASK
Get-ScheduledTask -TaskName 'TEMPTASK' -TaskPath '\KD\' | Start-ScheduledTask
#Unregister TEMPTASK
Unregister-ScheduledTask -TaskName 'TEMPTASK' -ErrorAction Ignore -Confirm:$false
}
#The scriptblock get the same parameters of the .ps1
Invoke-Command -ComputerName $Computer -ScriptBlock $script_task -ArgumentList $User, $Command, $Args
Usage example:
file.ps1 -User USER_NAME -Command notepad.exe -Computer REMOTE_COMPUTER
I don't know of any way you can control another open cmd session. However, you should be able to use runas to run it as another user.
This can be archived using Sysinternals tools from Microsoft. Beside running lists of commands and scripts remotely, they are useful for lot of things. As admin they had been my savior on multiple occasions.
#To run a command on single computer remotly
psexec \\RemoteComputerName Path_Of_Executable_On_Remote_Computer Argument_list
#To run a command on list of computers remotely.
psexec #Remote_Computer_list Path_Of_Executable_On_Remote_Computer Argument_list /AcceptEULA
#To run list of commands on list of remote computer. make sure you copy batch file before you run command below.
psexec #Remote_Computer_List Path_Of_Batch_On_Remote_Computer Argument_list