How can I remotely execute a script in Windows? - windows

I would like to have a Windows 2003 server fire a script to fire another script in a separate Windows Server 2008 computer.
I have been told that Powershell can do that, and that's fine, but I need more specific details.
Does anyone have any tips for this?
Thanks!

psexec from SysInternals

Look into the syntax for the AT command. You can use it to schedule a process to run on a remote machine.
The AT command schedules commands and programs to run on a computer at
a specified time and date. The Schedule service must be running to use
the AT command.
AT [\\computername] [ [id] [/DELETE] | /DELETE [/YES]]
AT [\\computername] time [/INTERACTIVE]
[ /EVERY:date[,...] | /NEXT:date[,...]] "command"
\\computername Specifies a remote computer. Commands are scheduled on the
local computer if this parameter is omitted.
id Is an identification number assigned to a scheduled
command.
/delete Cancels a scheduled command. If id is omitted, all the
scheduled commands on the computer are canceled.
/yes Used with cancel all jobs command when no further
confirmation is desired.
time Specifies the time when command is to run.
/interactive Allows the job to interact with the desktop of the user
who is logged on at the time the job runs.
/every:date[,...] Runs the command on each specified day(s) of the week or
month. If date is omitted, the current day of the month
is assumed.
/next:date[,...] Runs the specified command on the next occurrence of the
day (for example, next Thursday). If date is omitted, the
current day of the month is assumed.
"command" Is the Windows NT command, or batch program to be run.

easiest way that is use will be in two steps
a. installing cygwin to remote pc
b. run ssh hudson#mcs '/cygdrive/c/path_to_script.bat'

Speaking about PsExec, I would strongly suggest to use Cygwin/OpenSSH instead.
SSH has multiple advantages (over tools like PsExec or even custom-made services).
For example, try to use with PsExec and implement what these bash / ssh command lines do:
ssh user#remotehost "find . -name something" 2> all.errors.txt
ssh user#remotehost "grep -r something ."
if [ "$?" == "0" ]
then
echo "FOUND"
else
echo "NOT FOUND"
fi
Good Luck!
SSH transfers (!) remote stdout / stderr / exit status to local shell for inspection
(killer feature and common requirement to integrate remote execution into logic of local scripts)
Cygwin/OpenSSH provides standard POSIX shell environment
(efficient time investment, fundamental tools, cross-platform ready, compatible habits, etc.)
You can still/always run all native Windows application
(including automatic execution of *.bat files by cmd processor)
You can configure password-less auth using public keys
(think about unattended automated tasks)
Tip
There was one requirement I had problems with initially:
background sshd service had to execute apps in user's graphical session
(to make application window appear in desktop environment).
The acceptable solution for me was running sshd service directly in user's GUI session
(start automatically when user logs in, follow the link to see configuration file changes):
/usr/sbin/sshd -f /home/user/sshd_config

The accepted solution from http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Q_22959948.html is:
What I provide was a script that takes
parameters... In this case it takes 4.
1) Server: if you pass -server it will
only do that one server 2) List: You
can provide a list file of servers.
3) Service: Name of the service you
want to modify 4) Verbose: is not
used here.
I did have some mistakes that I
changed in the following code. To use
cut/paste the code into a file called
Set-RemoteService.ps1. Make sure to
set your executionpolicy to run
scripts... it will not by default. You
do that by using the
set-executionpolicy cmdlet. PS>
Set-Executionpolicy "RemoteSigned" to
run the script you do PS>
C:\PathToScript\Set-RemoteService.ps1
-list c:\ServerList.txt -service "DHCP"
######################### Param($server,$list,$service,[switch]$verbose)
if($Verbose){$VerbosePreference =
"Continue"} if($list) {
foreach($srv in (get-content $list))
{
$query = "Select * from Win32_Service where Name='$service'"
$myService = get-WmiObject -query $query -computer $srv
$myService.ChangeStartMode("Automatic")
$myService.Start()
} } if($server) {
$query = "Select * from Win32_Service where Name='$service'"
$myService = get-WmiObject -query $query -computer $server
$myService.ChangeStartMode("Automatic")
$myService.Start() }

Related

How to start long-running/background process from PowerShell completion mechanism?

I have a PowerShell completion hook that looks like:
$scriptblock = {
param($wordToComplete, $commandAst, $cursorPosition)
# ...
clap-json-test-completions power-shell query $wordToComplete $script:index -- #elements | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_)
}
}
Register-ArgumentCompleter -Native -CommandName clap-json-test -ScriptBlock $scriptblock
The clap-json-test-completions command is a program written in Rust which generates suggestions for the completing the current command line.
The clap-json-test-completions program is designed to talk to a local "server" process on the machine for certain bits of information that take longer to figure out and can be cached by the server process. If the server process isn't running then the clap-json-test-completions program attempts to start it up.
Unfortunately, the PowerShell completions mechanism waits until that server process stops before returning the suggestions to the user. As that server process is designed to not stop, this is an issue.
I have tried spawning the server process using:
.creation_flags(
DETACHED_PROCESS_FLAG
| CREATE_NEW_PROCESS_GROUP_FLAG
)
Based on the Creation Flags documentation in the Windows docs. Unfortunately they don't seem to have to desired effect. Instead of allowing the completion process to return whilst the server is still running, they just seem to make it so that Ctrl-C no longer kills the server from the hung completion prompt.
I've also tried launching the command a "Job" using:
Start-Job -ScriptBlock { clap-json-test-completions power-shell query $wordToComplete $script:index -- #elements } | Receive-Job -AutoRemoveJob -Wait | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_)
}
In the Power-Shell completion script and using CREATE_BREAKAWAY_FROM_JOB_FLAG as an additional creation flag but that doesn't seem to work.
I understand that Windows Services exist for long running processes but we would rather have a situation where the server only starts when the user first tries to do a completion and have a situation where the user has permissions to start the server (as a normal process) rather than requiring extra permissions to interact with the Windows Service system.
The current approach works fine if the clap-json-test-completions binary is run by itself outside of the completions system. It doesn't hang waiting for the server to finish.
Is there an approach to either the PowerShell completion script or the process creation in the Rust code that'll allow the completion system to return whilst the server still runs?

Poweshell Start-Job from serviceAccount using SailPoint IQService

So there are several factors in play with this question, so here they are:
SailPoint 8.2 and IQService 8.2
Windows Server 2016
A service Account(Domain Admin)
An interactive User account (Domain admin)
Powershell 5.1 build 14393 revision 4583
So what we have is SailPoint is executing a rule on its end, sending over some information to IQService, and IQService is executing the PowerShell scripts as the service account. In one of the PowerShell scripts, we have the following command:
LogToFile("calling start job")
$j = Start-Job -ScriptBlock { C:/SailPoint/Scripts/PowershellContainerAfterCreateRetry.ps1 -sAMAccountName $args[0] -company $args[1] } -ArgumentList $sAMAccountName, $company -Name 'PowershellContainerAfterCreateRetry'
LogToFile($j | Select-Object -Property *)
LogToFile("finished start-job")
and this is where things get interesting because this command, as you can note, we can log to file to see what its output is, which is as follows:
calling start job
#{
State=Running; HasMoreData=True;
StatusMessage=;
Location=localhost;
Command= C:/SailPoint/Scripts/PowershellContainerAfterCreateRetry.ps1 -sAMAccountName $args[0] -company $args[1] ;
JobStateInfo=Running;
Finished=System.Threading.ManualResetEvent;
InstanceId=aa889c06-7a8a-402e-807a-880d02465bdd; Id=1;
Name=PowershellContainerAfterCreateRetry;
ChildJobs=System.Collections.Generic.List`1[System.Management.Automation.Job];
PSBeginTime=10/15/2021 21:14:22; PSEndTime=;
PSJobTypeName=BackgroundJob;
Output=System.Management.Automation.PSDataCollection`1[System.Management.Automation.PSObject];
Error=System.Management.Automation.PSDataCollection`1[System.Management.Automation.ErrorRecord];
Progress=System.Management.Automation.PSDataCollection`1[System.Management.Automation.ProgressRecord];
Verbose=System.Management.Automation.PSDataCollection`1[System.Management.Automation.VerboseRecord];
Debug=System.Management.Automation.PSDataCollection`1[System.Management.Automation.DebugRecord];
Warning=System.Management.Automation.PSDataCollection`1[System.Management.Automation.WarningRecord];
Information=System.Management.Automation.PSDataCollection`1[System.Management.Automation.InformationRecord]}
finished start-job
When I execute this command either by itself OR within this script using Windows PowerShell ISE, it completes with no issue and calls the script in question, and everything works perfectly! (whether I am using my interactive account OR the service account)
When this script executes using the IQService, something "else" is happening - I say something "else" because I don't have any log files or errors; it just seems to disappear into the ether. (I have a log write out five lines into the PowerShell script, so one would think I would at least get SOMETHING!?!? I am out of ideas...thoughts?
As a minor note, I ran an experiment that showed me that there is something strange about the setup which should have succeeded without issue - like the above it appears to execute (because I can see the same information above, that shows that the job has started). Still, just like the above, it never actually "appears" to complete or error out. The only thing I can think of is that somehow the primary script closing out is causing this to close out as well - but I would think it would be able to get a couple of log files written to if that was the case? Anyway...thanks for reading!
$doit = {
"test" | Out-File -filepath ("c:\test.txt") -append
}
Start-job -ScriptBlock $doit
i think Start-Job is the problem here, as iqservice will launch a powershell script process and that may not support the background job aspect you are trying to use.
if you need to have something retry or wait and loop, you'll need to use another identityiq/iqservice mechanism (a workflow in iiq perhaps that calls down to AD when conditions are, timer is hit, etc.) beyond start-job inside of an iqservice powershell script.

Remotely execute `shutdown /sg`

I'm using a raspberry pi to shut down my Windows 10 Computer.
My RPI uses SSH with a private key to execute a shutdown /s /t 30 command on my computer.
But, for optimization reasons, I want to use the shutdown /sg command; by doing so my applications will open automatically before I unlock my session.
However, shutdown /sg needs to be executed on a Desktop Session.
How I can execute a script on my desktop from command communicated over SSH?
Thanks for your help.
I tried to use Invoke-Command but Powershell is not my cup of tea.
But, I find a solution :
I created a Task (named ShutdownSG_over_SSH_from_RPI) in Task Manager which execute shutdown \sg command.
From my RPI, I execute this command over SSH :
powershell -command "Start-ScheduledTask -TaskPath '\MyTaskPath\' -TaskName 'ShutdownSG_over_SSH_from_RPI'"
I know it isn't the best solution but it works.
If you have PowerShell 6.0, support for SSH connection has been added to New-PSSession, Enter-PSSession and Invoke-Command
This requires software to be installed on both your Raspberry PI and your computer.
Microsoft have provided a nice article explaining how to achieve this:
https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/ssh-remoting-in-powershell-core?view=powershell-6
You should also look at the documentation for Invoke-Command, as that's the easiest way to execute commands and scripts remotely:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-6

Executing powershell command for getting megaraid status and sending output to mail using task scheduler in windows2012

I have windows 2012 server with LSI Megaraid controller. I am able to get raid status using below command in powershell and redirect output to a file.
C:\> MegaCli64.exe -LDInfo -Lall -aALL | Out-File raid.txt
However I tried to run same command using task scheduler and it is not working. I want to send the output of raid command or send raid.txt to a mail using task scheduler.
Some piece of advise for sceduled jobs :
1) Always set the working directory if you work with local files.
2) Always use the full path (not the relative one) for the programs you call and the files you manipulate. Do not expect the exe you call being in the paths pointed by $env:path.
3) Put your commands into a script file and make sure that a log (any type), with a time stamp, is composed each time your script is called.
4) Here is one way, but it exits multiples ways, to register your script in the scheduler :
# First set a Trigger
$SixInTheMorning = New-JobTrigger -Daily -At "06:00 AM"
# Second set your script
$scriptPath1 = 'C:\Batchs\WS_PowerShell\Myscript.PS1'
# Third register you job
Register-ScheduledJob -Name "AJobName" -FilePath $scriptPath1 -Trigger $scriptPath1

Run powershell script whenever a server reboot is initiated and show the script progress in cmd

I need to run a powershell script whenever the server is rebooted/shutdown (whether graceful or disgraceful reboot).
The script will stop 4 application services at an interval of 1 minute and then finally reboots the system.(This is a business requirement, don't ask why)
How can I make server to invoke the .ps1 script whenever a reboot or a shutdown is initiated.
My test results:
I tried to create a test script which will generate a text file with current date/time and added it to the scheduled task on the trigger of event log 6006 (which is created whenever a system reboot/shutdown is initiated.)
I checked the box -"Run with highest privileges" but after system restart no text file was generated as it was supposed to, although it generates when ran manually.
Do we have any better approach to implement this?
(My final expectation should look like this-
On a random day a random user initiated reboot after a monthly patch when a command prompt window opens before him with message something like:
Stopping service abc...
Stopped.
Waiting for 60 seconds.
Stopping service xyz...
Stopped
EDIT: I've been successfully able to invoke the .ps1 file by adding it to the gpedit as suggested by Kory and Alroc but the script runs only in background when computer restart is initiated. It doesn't opens a regular cmd window to show the progress.
I'm adding the .ps1 script as well below which stops 2 services(chosen for testing purpose) at an interval of 10 seconds and will show the timer as well, only when ran manually.When invoked by the shutdown command it'll stop services only in the background without showing the progress to the user. Kindly assist to achieve this?
Write-Host "Shutdown script invoked"
stop-service W32Time -force -PassThru
for($i = 10 ; $i -gt 0 ; $i--)
{
Write-Progress -Activity "`n Waiting for" -status "`$i equals $i seconds"
sleep 1
}
stop-service wuauserv -force -PassThru
You can use GPO to configure a shutdown script for systems.
You might be able to to it via a Win32_ComputerShutdownEvent watcher as well.
After deep digging, I've finally figured out how to make the cmd window visible while system shutdown in progress.
Here is the complete steps of performing above mentioned expectation:
Open gpedit.msc
Navigate to Computer Configuration->Windows
Settings->Scripts(Startup/Shutdown)->Shutdown.
Go to Shutdown properties. In the powershell scripts tab add your
script and select 'Run Windows Powershell script first'
Above steps will enable the invoke of script at every system shutdown. Now to make the script visible and show progress:
Navigate to Computer Configuration->Administrative
Templates->System->Scripts
Among the policies showing in the right pane enable below
properties:
Run Windows Powershell scripts first at computer start,shutdown
Run shutdown scripts visible

Resources