Install remotely with powershell - powershell

I want to build a script that will Install remotely HP OM agent. Is there any good way to Install it, without having the install files on the remote computer?
this script will install remotely the HP agents for list of servers. I thought to copy the files from my computer to each server and after that to install it. I'm sure there is a better way to do it.
To install the agent I need to run the command :
cscript "\c:\pathToTheAgentFile" -i -a -minprecheck

Using Invoke-Command with the ScriptBlock parameter should accomplish this task so long as a silent install method is used.
$ComputersList = #("computer","names","here","replace","me")
$PathToShare = "\\path\to\install_replace_me.exe"
$CommonLocalComputerPath = "C:\replace_me.exe"
$SilentInstallArgs = "/example","/replace"
$AdministratorCreds = [System.Management.Automation.PSCredential]::Empty
$ComputersList | ForEach-Object {
Invoke-Command -ComputerName $_ -ScriptBlock { Copy-Item $Using:PathToShare -Destination $Using:CommonLocalComputerPath -Credential $Using:AdministratorCreds;
Start-Process $Using:CommonLocalComputerPath -ArgumentList $Using:SilentInstallArgs -Credential $Using:AdministratorCreds} -Credential $AdministratorCreds
}
The above script will prompt for administrative credentials, authenticate to a remote share that holds the installer from the remote computer, copy the installer to the remote computer, and then start the installer on the remote computer. You will have to verify the installs manually as it will not return any data except in the event of a terminating error. The script will have to be modified to point to the correct locations for your environment.

Related

Powershell/batch uninstall script works locally but not when using invoke-command

I have a script that installs an .exe with some arguments remotely to a list of servers that works fine. When I try to do almost the exact same thing but run the uninstall.exe that gets installed to C:\Program Files (x86)\ it won't work.
When I run the scripts on the server locally, it kicks off the uninstall. When I try to run the exact same script or command using the powershell invoke-command it won't work.
$serverlist = Get-Content -Path C:\NagiosInstall\test.txt
ForEach ($server in $serverlist) {
New-Item -Path "\\$server\C$\" -Name "NagiosInstall" -Force -ItemType "directory"
Copy C:\NagiosInstall\ncpa-2.1.6.exe \\$server\C$\NagiosInstall\ncpa-2.1.6.exe
Copy C:\NagiosInstall\install.bat \\$server\C$\NagiosInstall\install.bat
invoke-command -ComputerName $server -ScriptBlock {C:\NagiosInstall\install.bat}
Start-Sleep -s 15
invoke-Command -ComputerName $server -ScriptBlock {Remove-Item -LiteralPath "C:\NagiosInstall" -Force -Recurse}
}
The install .bat is just a simple command to silently install that ncpa-2.1.6.exe.
Above is my install script, that part all works fine.
invoke-command -ComputerName $server -ScriptBlock {Start-Process -FilePath "C:\Program Files (x86)\Nagios\NCPA\uninstall.exe" -ArgumentList "/S"}
Running the above command, nothing happens. No errors, nothing.
& "C:\Program Files (x86)\Nagios\NCPA\uninstall.exe" -ArgumentList "/S"
But running the above command in powershell that's running as admin locally on the server and it works just fine.
I've also tried the same approach to create and copy and run a batch file, very similar to the above "install" code. Same thing... nothing happens but if you run the batch locally on the server, it works just fine. I can post this code if anyone is interested.
I'm guessing it has to do with the invoke-command or the fact that it's in C:\Program Files (x86) which might make the syntax different, but I've tried many things and I'm out of ideas besides making an account and posting here.
The issue is that Invoke-Command runs non-interactively, and therefore cannot run as Administrator and respond to a UAC prompt.
The only workaround is to connect to the computer via a PSSession with credentials, and execute it that way:
$Cred = Get-Credential
$Session = New-PSSession -ComputerName $server -Credential $Cred
Invoke-Command -Session $Session -ScriptBlock {Start-Process -FilePath "C:\Program Files (x86)\Nagios\NCPA\uninstall.exe" -ArgumentList "/S"}
$Session | Exit-PSSession
Edit:
The reason that the installer works is that the UAC prompt for Windows Installs is different than anything else in Windows see: How to Silence the UAC Prompt for Per-Machine MSI Packages for Non-Admins or Using Windows Installer with UAC.
Essentially, Windows Installer (already running as admin and UAC approved), is what runs the install on your behalf, and it is Windows Installer and installer settings that determines if you need to see a UAC prompt or not. Hence, this is why the install works. Windows Installer determined that you did not need to see the UAC prompt, and the install proceeds.
Uninstalling is different. Since you are running uninstall.exe, the executable needs admin access and Windows will do UAC before the uninstall.exe even runs.

PowerShell Remote Installation of exe - Not able to install

I am trying to install exe on remote machine by using below script, but it didn't succeed. The exe file is on remote machine.
Invoke-Command -ComputerName COMPUTER -ScriptBlock{
Start-Process c:\Windows\Temp\ccsetup.exe -ArgumentList '/silent' -Wait
}
I tried giving different paths but it is not helpful.

Automated Uninstall Service via MSI Not Working

I am writing a powershell script to deploy a .NET 4 Windows Service to a 2008 server via a generated MSI. A fresh installation runs fine, but when I rerun and it tries to uninstall it, the script hangs while trying to do the uninstall. I call msiexec, which runs on the target machine (I can see the process started when the uninstall is running). The only differences between the uninstall and install code is the log name and the /x command passed to msiexec.
Here is the code that I have:
function UninstallService ($serverName, $fileName)
{
write "Start uninstall service."
$msiNamePath = "C:\MsiDeployment\" + $fileName
$processArgs = #("/i", $msiNamePath, "/x", "/qn", "/norestart", "/l", "c:\msiuninstall.log")
# Create session
$session = New-PSSession -ComputerName $serverName
# Enter session
Enter-PSSession $session
# Do uninstall
Invoke-Command -Session $session -ScriptBlock { param($pArgs,$rootDir) Start-Process -FilePath "$rootDir\msiexec.exe" -ArgumentList $pArgs -Wait } -Args $processArgs,("$env:systemroot\system32")
# Close session
Exit-PSSession
Remove-PSSession $session
if (!$?) { throw "Could not uninstall the service remotely on machine " + $serverName }
write "End uninstall service."
}
If I terminate the running msiexec on the server, the script continues on processing (fails later due to checking if the service is uninstalled). I'm guessing that there is some prompt that is looking for user input (maybe UAC), but I'm not entirely certain. I get no log file on the uninstall, but install writes the log file.
Enter-PSSession is meant only for interactive use and not in a script. So, essentially, your script stops working after Enter-PSSession $session.
Remove the following lines from your script and everything should work as expected.
# Enter session
Enter-PSSession $session
# Close session
Exit-PSSession
All you need is the Invoke-Command.
Actually, I figured out the issue. I left the /i flag in the arguments when it should have just been the /x flag. Works fine now.
The flag was the msiexec throwing an error page even when the qn flag was passed to it. Not sure if it should have done that.

Linux executes a command on a remote Windows server without SSH/Telnet

I am building a Jenkins server. One of the deployment steps is to execute a command on the production server to download the UAT-tested artifacts to the required folders. Jenkins is running on CentOS Linux while the production server is running Windows 2008 R2.
However, my client does not want to install any software into the production server, therefore executing commands via SSH is not possible. The client had an unpleasant experience with using Telnet before. It is an insecure service which has already been disabled on the server.
Other than using SSH and Telnet, are there other ways to execute a command on a remote machine? I was thinking of creating a task that is triggered by a specific event, but how to raise the event on the server remotely seems not an easy job.
I can think of four different solutions:
Have a network share on the production machine that your Jenkins server can put a trigger file into. Have a scheduled task that checks for that file and triggers the download.
Have a scheduled task on the production machine poll the Jenkins server for new files. Powershell can be used to query the Jenkins REST api.
If the production machine has IIS, get Jenkins to trigger an asp.net script, do a form POST to a cgi script, or upload a trigger file. curl and wget on CentOS will help there.
As a last resort, add another windows machine into the mix. Install SSH onto it. Use SSH from Jenkins to the new machine, then powershell from the new machine to the production machine.
If you decide on step 4, I use Power Shell to run commands on a remote machine.
PS2.0 is installed on Windows 2008 R2 by default.
Here is an example of how I do it.
$username = 'user'
$password = 'password'
$appHost = 'hostname'
$dest = 'C:\Unpack\'
$archive = "C:\Releases\new release.7z"
$securePass = ConvertTo-SecureString -AsPlainText $password -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$securePass
"Create PowerShell Session"
$appSession = New-PSSession -ComputerName $appHost -Credential $cred -Authentication CredSSP
invoke-command -session $appSession -scriptblock { param($dest,$archive) & 'C:\Program Files (x86)\7-Zip\7z.exe' x -bd -aoa """-oc:\$dest""" """c:\$dest\$archive"""} -args $dest,$archive
$remotelastexitcode = invoke-command -session $appSession -ScriptBlock { $lastexitcode }
if ( $remotelastexitcode -ne 0 )
{
"Archive Extraction Failed. Is a file locked or open?"
exit -1
}

Can you run remote commands without psexec?

I am attempting to run a batch file on several remote machines. It has some registry changes and other commands that I am able to run remotely. I have one command I have not been able to figure out an alternative:
net user USERNAME /PASSWORDREQ:yes
Is there a way to run this command remotely without psexec? I'd rather not distribute my batch file with a dependancy.
Yes, you can enable powershell remoting on the remote computers, and then use the Invoke-Command cmdlet. Example:
Invoke-Command -ComputerName RemoteComputer -Script { param($userName) net use $userName /PASSWORDREQ:yes } -Args "UserNameArgumentValue"