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.
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.
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;}
Get-Content Servers.txt | ForEach-Item {
$remoteDest = "\\$_\c`$\some\temp\folder"
$localDest = "C:\some\temp\folder" | Join-Path -ChildPath ($InstallerFolderPath | Split-Path -Leaf)
try {
Copy-Item -Path $InstallerFolderPath -Destination $dest -Force
Invoke-Command -ComputerName $_ -Credential $mycreds $ScrBlock -ArgumentList $localDest
finally {
Remove-Item $remoteDest -Force -ErrorAction Ignore
}
}
}
InstallApp -ServerNameFilePath $ServerNameFilePath -InstallerFolderPath $InstallerFolderPath -UserName $UserName -Password $Password
[PSCredential]
parameter. You can use a default value that prompts, like [PSCredential] $Cred = (Get-Credential)
. (this is not addressed in my code either).