I have a PowerShell script, that run's at user log in on one VM (00000281):
Get-Content C:/sample.txt -TotalCount 1) | Set-Content C:\sample.txt
To execute the script automatically I have created a .cmd file and placed it in the following folder:
C:\Users\vs_domadmin\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
The above VM(00000281) resides in my infra VM's cluster which contains four other Vm's (infra servers). I have a total of four servers, which I would like that script to run as well.
00000281, 00000282, 00000283, 00000284
My script is running for the moment only on the 00000281. Here is the trick:
I need that script from 00000281 to execute also on the rest of the infra servers 00000282, 00000283, 00000284, knowing that the script will be stored only on my first infra server 000002821. I believe that giving the script some conditions and outlining the path of the other 3 VMs in VM (00000281) should do the work correct>
VM 00000282, 00000283, 00000284 is considered as a remote machine w.r.t the current user in vm 00000281.
You have to run the script in the machine itself using the powershell Remote process of the same machine by configuring the 4 machines to run remote powershell script.
This done by enabling every machine to run the powershell remote service WinRM
For step by step details:
How to Run PowerShell Commands on Remote Computers
Modify the script in vm 00000281, add this as last line:
Invoke-Command -ComputerName 00000282, 00000283, 00000284 -FilePath path_to_script_file.ps1
In this way you run concurrently the same script in all machines.
Login user should have a permission in these machines.
Solution identified:
$File = "C:\sample.txt"
Get-Content $File -TotalCount 1 | Set-Content $File
"00000282", "00000283", "00000284" | % {
$FileUnc = "\\$($_)\$($File.Replace(':', '$'))"
Get-Content $FileUnc -TotalCount 1 | Set-Content $FileUnc
}
Related
Wondering if anyone knows how to/if it is even possible to resize a PowerShell windows that I open on a remote computer using the batch file I used to run it.
1 #ECHO OFF
2 title Remote Start ProgramName Server
3 cd "C:\IT\FOLDER"
4
5 #ECHO OFF
6 SET /p _computer=Computer Name:
7
8 #ECHO "Launching Program Server On Remote PC %_computer%"
9
10 start PowerShell.exe .\psexec -i \\%_computer% '"C:\Program Files\ProgramFolder\programserver.exe"'
11
12 #ECHO "Launching ClientSideProgram on Local Machine"
13 start "" "C:\Program Files\ProgramFolder\programclient.exe"
14
15 PAUSE
16
17 start "" PowerShell.exe .\pskill \\%_computer% programserver.exe
18 ECHO "Program Server Terminated"
19
20 PAUSE
So as far as I have tested this, it works, but when I do start PowerShell.exe on line 10, it, as expected opens a powershell. THIS is the powershell I would like to resize to the smallest possible size, so that it's not as big of a nuisance when it opens.
Thanks in advance for whatever help anyone has
Edit: If resizing is not possible, can I just 'hide' it? or move it to the background at all?
This is a batch file that is just using PowerShell to call psexec.
Either use PowerShell Remoting ---
Running Remote Commands
Start an Interactive Session To start an interactive session with a
single remote computer, use the Enter-PSSession cmdlet. For example,
to start an interactive session with the Server01 remote computer,
type:
Enter-PSSession Server01
Run a Remote Command To run a command on one or more computers, use
the Invoke-Command cmdlet. For example, to run a Get-UICulture command
on the Server01 and Server02 remote computers, type:
Invoke-Command -ComputerName Server01, Server02 -ScriptBlock {Get-UICulture}
--- or use PSexec and target that remote host.
PsExec - Windows Sysinternals | Microsoft Docs
Using psExec to Open a Remote Command Window
https://blogs.technet.microsoft.com/systemcenteressentials/2009/09/01/using-psexec-to-open-a-remote-command-window
psExec \computer cmd
PsExec (SysInternals)
Execute a command-line process on a remote machine.
Much of PSRemoting requires that you use an account that is in the local admin group on the target. However, there are some that do not.
The only reason to use PSExec over PSRemoting is if PSRemoting is not enabled and if you need to run Code in the context of the logged on user.
# PowerShell only via PSRemoting
$TargetComputerName = Read-Host -Prompt 'Enter a computer name.'
Invoke-Command -ComputerName $TargetComputerName -ScriptBlock {
'C:\Program Files\ProgramFolder\programserver.exe'
} -Credential 'contoso\administrator'
# PSExec only
psexec \SomeTargetComputerName -c C:\Program Files\ProgramFolder\programserver.exe
With PSRemoting nothing is ever displayed on the targethost.
With that PSExec command, nothing is ever displayed on the targethost.
If you use PSExec to run in the context of the logged on user on that target host, then stuff will display when you call PowerShell.exe unless you use the minimize or hide switches.
This indicates that you are new to PowerShell and PowerShell remoting commands. Please hit up YouTube and view some of the talks on PSRemoting, running remote command, running remote programs, well, PowerShell in general.
Found the answer from a fellow colleague of mine. Apparently, very easy to just star minimized.
start /MIN
will do just that
Steps:
1. I have created a file known as: "test.vbs" under temp folder in machine B and in that script i have msgbox "hi"
2. From machine A - my goal is execute to test.vbs in machine B
3. In machine A. i did the following steps but i didnt get remote script executed. Can anyone please help me.
ps c:/> $s=new -pssession -computername machineB
ps c:/> Invoke-Command -Session $s-ScriptBlock{$filecount=(Get-ChildItem c:\temp\test.vbs -Recurse)}
ps c:/> Invoke-Command -Session $s-ScriptBlock{$filecount}
i received directory c:\temp and a file name as test.vbs
Now i want to execute test.vbs
ps c:/> Invoke-Command -ComputerName MachineB{& "C:\Temp\test.vbs"}
After executing the above command i dont see the test.vbs not executing remotely.
my expectation is to get hi messagebox.
I am not understanding if it got executed or not.
can anyone please help me to execute remote script locally using power shell.
thanks inadvance.
If my understanding to your question is correct, you want to execute test.vbs against machine B from machine A, I don't think it's possible in PowerShell.
I faced the same issue some time ago. Neither Enter-PsSession nor Invoke-Command can do it for you probably just because they are not designed for this purpose. They are working totally fine if you run any PowerShell cmdlets remotely e.g. Get-Item you can easily get items on machine B. But once if you try to do something beyond the PowerShell remote session, like run a vbs script which will start a new CScript.exe process, it just won't work. It's due to some reason in underlying implementation of this PowerShell remoting.
If you do need to do that, I got two workarounds
PsExec can be the best solution. It was designed to do this kind of work originally and it can easily accomplish what you want with a bunch of advanced features.
Create a scheduled task on machine B by using New-ScheduledTask and let it trigger itself on machine B locally.
If you have SCCM installed, it also provides this kind of functionality, check out this blog.
Current PS script:
Invoke-Command -ComputerName RemoteServer007.FQDN.com -ScriptBlock {
Set-Variable -Name WOWCONFIG -value "d:\ABCs\WOWzers" `
| Start-Process "d:\da-folder\Do-It-NOW-Pleez.cmd"
}
If I log on locally to the server(RemoteServer007.FQDN.com) and execute the cmd file, it runs through all of the lines(commands) within the cmd file.
When I execute it remotely, it gets about 30% of the way through the commands within the cmd file, the PS execution ends without error, but not all of the lines/commands in the cmd file had been executed.
This was discovered by simply configuring each line of the cmd file to output to txt files.
I even tried re-ranging the commands in the cmd file, thinking that perhaps there was a specific command that was causing it to exit, but that is not the case.
I'm wondering if there is some timeout or response that PowerShell is not getting? and just quitting almost immediately after starting?
Any ideas or help would be greatly appreciated.
There are a couple of things you can do here:
You may have a memory issue. Increasing the value of MaxMemoryPerShellMB might help
set-item WSMan:\$target\Shell\MaxMemoryPerShellMB -Value 0 -Force
You'd need to run this once on the remote machine before you execute your commands again.
You can also see possible error logs in the windows event viewer. There are categories for powershell and for Windows Remote Management which you should look at.
Finally, you can just run this process asynchronously, using the task scheduler for instance. I had a similar problem with windows in the past, and running the process from the task scheduler, outside the powershell session, fixed it. There's an example of how we did this in Cloudify here:
https://github.com/CloudifySource/cloudify/blob/master/esc/src/main/resources/clouds/ec2-win/upload/bootstrap-management.ps1#L220
I use the following command to run setup_server.exe on remote Windows box:
powershell -command "$encpass=convertto-securestring -asplaintext RPASSWORD -force;$cred = New-Object System.Management.Automation.PSCredential -ArgumentList RUSER,$encpass; invoke-command -computername RCOMPUTERNAME -scriptblock {setup_server.exe} -credential $cred;"
setup_server.exe's task is to create some configuration files and start my_server.exe (some daemon process), then it finishes. And I want my_server.exe to keep running after setup_server.exe is finished.
So when I do it via CMD on local box (i.e. just run setup_server.exe from CMD) it works, but when I do it via powershell on remote host it doesn't work. Namely the my_server.exe gets started, but right after setup_server.exe is closed the server also gets closed(killed).
So the question is following:
Which powershell flags/cmdlets should I use to make the described scenario to work as in local mode?
NOTE: I want synchronously get output of setup_server.exe, so running remote command with -AsJob flag, probably wouldn't work for me, though I even don't know if it will keep the server alive after setup_server.exe's end.
The way to keep the remote PowerShell session running after the command has finished is to use a PSSession e.g.:
$s = new-PSSession computername
Invoke-Command -session $s { ..script.. }
... do other stuff, remote powershell.exe continues to run
Remove-PSSession $s # when you're done with the remote session
Generally though exes should run independently from the app that launched them.
Why are you using Invoke-Command. If you want a persistent Session, use Enter-PSSession.
$s = New-PSSession -Computername "Computername";
Enter-PSSession -Session $s;
setup_server.exe
# Once you are finnished
Exit-PSSession
With 'Enter-PSSession' you are not just Invoking some Command on the Server, you are directly logged-in like you probably know from SSH.
If you want your powershell session to keep running because you are running an exe, try using the -InDisconnectedSession switch. From what I understand, it will run the executable on the remote machine in a session that isn't actually connected to your computer. In essence, your computer will not destroy the session, when it disconnects, allowing the exe to continue to run.
invoke-command -computername RCOMPUTERNAME -scriptblock {start-process setup_server.exe} -InDisconnectedSession
If you need to do this on multiple computers. Setup an array of all the computer names.
Note: I don't believe this works with sessions that are already created.
In order to keep a powershell code running on the session exit it should be a process. And the windows way to keep the process is running a .exe or a windows service.
To keep a Powershell shell open after executing a command, I use the -NoExit switch, e.g. this script starts a remote interactive PS session on servername with user administrator
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoExit
-Command "Enter-PSSession -ComputerName servername -Credential administrator"
http://powershell-guru.com/powershell-tip-13-prevent-powershell-from-exiting-once-script-finished/
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() }