Delete/Disable windows scheduled task Remotely - windows

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
}

Related

Using ssh to connect to Windows machine and start Docker Desktop in user's space [duplicate]

I've created a pssession on a remote computer and entered that possession. From within that session I use start-process to start notepad. I can confirm that notepad is running with the get-process command, and also with taskmgr in the remote computer. However, the GUI side of the process isn't showing. This is the sequence I've been using:
$server = New-PSSession -ComputerName myserver -Credential mycreds
Enter-PSSession $server
[$server]: PS C:\>Start-Process notepad -Wait -WindowStyle Maximized
The process is running, but while RDP'd to the box, notepad does not open. If I open notepad from the server, a new notepad process begins. I also tried by using the verb parameter like this:
[$server]: PS C:\>Start-Process notepad -Wait -WindowStyle Maximized -Verb Open
Same result tho... Process starts, but no notepad shows. I've tried this while remoted into the box (but issued from my local host) as well as before remoting into the server.
That is because your powershell session on the remote machine does not go to any visible desktop, but to an invisible system desktop. The receiving end of your powershell remote session is a Windows service. The process is started, but nor you nor anyone else can ever see it.
And if you think about it, since multiple users could RDP to the same machine, there is really no reason to assume a remote powershell session would end up showing on any of the users desktops. Actually, in almost all cases you wouldn't want it anyway.
psexec with the -i parameter is able to do what you want, but you have to specify which of the sessions (users) you want it to show up in.
I know this is old, but I came across it looking for the solution myself so I wanted to update it for future poor souls.
A native workaround for this problem is to use a scheduled task. That will use the active session
function Start-Process-Active
{
param
(
[System.Management.Automation.Runspaces.PSSession]$Session,
[string]$Executable,
[string]$Argument,
[string]$WorkingDirectory,
[string]$UserID
)
if (($Session -eq $null) -or ($Session.Availability -ne [System.Management.Automation.Runspaces.RunspaceAvailability]::Available))
{
$Session.Availability
throw [System.Exception] "Session is not availabile"
}
Invoke-Command -Session $Session -ArgumentList $Executable,$Argument,$WorkingDirectory,$UserID -ScriptBlock {
param($Executable, $Argument, $WorkingDirectory, $UserID)
$action = New-ScheduledTaskAction -Execute $Executable -Argument $Argument -WorkingDirectory $WorkingDirectory
$principal = New-ScheduledTaskPrincipal -userid $UserID
$task = New-ScheduledTask -Action $action -Principal $principal
$taskname = "_StartProcessActiveTask"
try
{
$registeredTask = Get-ScheduledTask $taskname -ErrorAction SilentlyContinue
}
catch
{
$registeredTask = $null
}
if ($registeredTask)
{
Unregister-ScheduledTask -InputObject $registeredTask -Confirm:$false
}
$registeredTask = Register-ScheduledTask $taskname -InputObject $task
Start-ScheduledTask -InputObject $registeredTask
Unregister-ScheduledTask -InputObject $registeredTask -Confirm:$false
}
}
When you use New-PSSession and then RDP into that same computer, you're actually using two separate and distinct user login sessions. Therefore, the Notepad.exe process you started in the PSSession isn't visible to your RDP session (except as another running process via Task Manager or get-process).
Once you've RDP'd into the server (after doing what you wrote in your post), start another Notepad instance from there. Then drop to PowerShell & run this: get-process -name notepad |select name,processid
Note that there are two instances, each in a different session.
Now open up Task Manager and look at the user sessions. Your RDP session will probably be listed as session 1.
Now quit Notepad and run get-process again. You'll see one instance, but for session 0. That's the one you created in your remote PSSession.
There are only 2 workarounds that I know of that can make this happen.
Create a task schedule as the logged in user, with no trigger and trigger it manually.
Create a service that starts the process with a duplicated token of the logged in user.
For the task schedule way I will say that new-scheduledtask is only available in Windows 8+. For windows 7 you need to connect to the Schedule Service to create the task like this (this example also starts the task at logon);
$sched = new-object -ComObject("Schedule.Service")
$sched.connect()
$schedpath = $sched.getFolder("\")
$domain = "myDomain"
$user="myuser"
$domuser= "${domain}\${user}"
$task = $sched.newTask(0) # 0 - reserved for future use
$task.RegistrationInfo.Description = "Start My Application"
$task.Settings.DisallowStartIfOnBatteries=$false
$task.Settings.ExecutionTimeLimit="PT0S" # there's no limit
$task.settings.priority=0 # highest
$task.Settings.IdleSettings.StopOnIdleEnd=$false
$task.settings.StopIfGoingOnBatteries=$false
$trigger=$task.Triggers.create(9) # 9 - at logon
$trigger.userid="$domuser" # at logon
$action=$task.actions.create(0) # 0 - execute a command
$action.path="C:\windows\system32\cmd.exe"
$action.arguments='/c "c:\program files\vendor\product\executable.exe"'
$action.WorkingDirectory="c:\program files\vendor\product\"
$task.principal.Id="Author"
$task.principal.UserId="$domuser"
$task.principal.LogonType=3 # 3 - run only when logged on
$task.principal.runlevel=1 # with elevated privs
# 6 - TASK_CREATE_OR_UPDATE
$schedpath.RegisterTaskDefinition("MyApplication",$viztask,6,$null,$null,$null)
Creating a service is way more complicated, so I'll only outline the calls needed to make it happen. The easy way is to use the invoke-asservice script on powershell gallery: https://www.powershellgallery.com/packages/InvokeAsSystem/1.0.0.0/Content/Invoke-AsService.ps1
Use WTSOpenServer and WTSEnumerateSessions to get the list of sessions on the machine. You also need to use WTSQuerySessionInformation on each session to get additional information like username. Remember to free your resources using WTSFreeMemory and WTSCloseServer You'll end up with some data which looks like this (this is from the qwinsta command);
SESSIONNAME USERNAME ID STATE
services 0 Disc
>rdp-tcp#2 mheath 1 Active
console 2 Conn
rdp-tcp 65536 Listen
Here's an SO post about getting this data; How do you retrieve a list of logged-in/connected users in .NET?
This is where you implement your logic to determine which session to target, do you want to display it on the Active desktop regardless of how it's being presented, over RDP or on the local console? And also what will you do if there is no one logged on? (I've setup auto logon and call a lock desktop command at logon so that a logged in user is available.)
You need to find the process id of a process that is running on the desktop as that user. You could go for explorer, but your machine might be Server Core, which explorer isn't running by default. Also not a good idea to target winlogon because it's running as system, or dwm as it's running as an unprivileged user.
The following commands need to run in a service as they require privileges that only system services have. Use OpenProcess to get the process handle, use OpenProcessToken to get the security token of the process, duplicate the token using DuplicateTokenEx then call ``CreateProcessAsUser``` and finally Close your handles.
The second half of this code is implemented in invoke-asservice powershell script.
You can also use the sysinternals tool psexec, I didn't list it as a 3rd way because it just automates the process of creating a service.

windows schedule task could not successfully run at startup

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.

Runas in another Windows terminal session

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

How to start a program in another Windows Terminal session? (as an Administrator) [duplicate]

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

One-time scheduled task that fires on logon for another local user in Powershell

I'm trying to create a one-time scheduled task that fires on login for a local user that is not the user creating the scheduled task. What is the Powershell to do this? I'm using Powershell v3 on Win Server 2012 R2 and Windows 8.1. I need the task to run a line of powershell.
Moving my comment to an answer so this can be resolved.
If you're going to immediately reboot and login as that user just put it in :
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
Then the next user to login (any user) will initiate the command.
Schedule it to run from this registry key. The gotcha is you'll need to do it through the HKEY_USERS\SID instead of CurrentUser.
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_USERS\S-1-6236236236124362346346-BIG-LONG-NUMBER\Software\Microsoft\Windows\CurrentVersion\RunOnce
Here is how to get the users SID.
$objUser = New-Object System.Security.Principal.NTAccount("KNUCKLE-DRAGGER")
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$strSID = $strSID.Value
$strSID
Then drop that $strSID variable inside the HKEY_USERS path to automate creating the command in the correct location.
Set-ItemProperty -Path "registry::HKEY_USERS\$strSID\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "MyBatch" -Value "C:\SomeScript.cmd"

Resources