I need to install an application in several remote servers in quiet mode. I have created a script (Installer.ps1) like below using Powershell v3.0:
param(
[String] $ServerNameFilePath = $(throw "Provide the path of text file which contains the server names"),
[String] $InstallerFolderPath = $(throw "Provide the Installer Folder Path. This should be a network location"),
[String] $UserName = $(throw "Provide the User Name"),
[String] $Password= $(throw "Provide the Password")
)
Function InstallApp
{
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($UserName, $secpasswd)
$ScrBlock = {param($InstallerFolderPath) $ExePath = Join-Path $InstallerFolderPath "ServerReleaseManager.exe"; & $ExePath /q;}
Invoke-Command -ComputerName (Get-Content Servers.txt) -Credential $mycreds $ScrBlock -ArgumentList $InstallerFolderPath
}
InstallApp -ServerNameFilePath $ServerNameFilePath -InstallerFolderPath $InstallerFolderPath -UserName $UserName -Password $Password
Then I call the script like below (Installer folder path can have white spaces and the executable ServerReleaseManager.exe accepts argument):
.\Installer.ps1 -ServerNameFilePath Servers.txt -InstallerFolderPath "\\TestServer01\Public\Stable Applications\Server Release Manager Update 2\2.7" -UserName "Domain\User" -Password "Test123"
I am getting below CommandNotFoundException
always:
The term '\\TestServer01\Public\Stable Applications\Server Release Manager Update 2\2.7\ServerReleaseManager.exe' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I have tried other options like using -FilePath
with Invoke-Command
but same error. I am really blocked here. Can you please let me know why this error has shown? How to resolve the error? Or are there any better ways to deal with this. Thanks for your help.
Here I created a new PSsession to each server in the list and used the invoke command to target that server's session. I've tested it in my environment and it successfully installs my exe application with a /q switch on my remote servers.
This method however does not tell if you the command ran successfully on the remote side, you would have to logon to the server or do a test-path to the expected location of the installed files for validation. Also, PSsessions are held open until the console that launched the command is closed. If a PSsession ends before the install completes, the install will fail.
Desired state configuration can be used to install software on target machines. I assume this can work around the double hop issue.
http://technet.microsoft.com/de-de/library/dn282132.aspx
http://technet.microsoft.com/de-de/library/dn282129.aspx
By the way - dont throw errors for missing mandatory arguments. Let PowerShell handle that - it's much more user friendly:
This sounds like a double-hop authentication issue. Once you're remoted into the server, you can't access a file share on a third server because you can't pass your kerberos-based authentication to it.
You could try copying from the share to the remote server, first (this has to be done on the computer executing the script), and then in the scriptblock refer to the (now local) path.
You could set up CredSSP which isn't a great idea for this purpose.
Basically, you need to avoid connecting to one machine, then connecting to another through that connection.
Code that implements the workaround I'm describing:
Notes
[PSCredential]
parameter. You can use a default value that prompts, like[PSCredential] $Cred = (Get-Credential)
. (this is not addressed in my code either).