VMware Cloud Community
AymanSammour
Contributor
Contributor
Jump to solution

scriptBlock

I am having an issue passing Arrays to scriptblock. to substitute the variables, in order to run this script on the remote server using the invoke-vmscript   

the code below will install agents on windows server after it has been deployed.

 

foreach ($Agent in $WinoswsAgnetsList) {

$AgentName=$AgentFile= $ListofServices= $ArgumentList=$MSIArguments= $DataStamp=$logFile=$InstallerFullpath =$AgentDetails=$null
write-host "Now processing $Agent"
$AgentDetails=Select-HashTable -Hashtable $loadVars -Include $Agent
Write-Host $AgentDetails
$AgentName =$AgentDetails.Keys
$AgentFile =$AgentDetails.values.AgentName
$ListofServices =$AgentDetails.values.ListofServices
$Operators =$AgentDetails.values.ArgumentList
if (-not([String]::IsNullOrWhiteSpace( $ListofServices))){
$ListofServices= $ListofServices.split(",")}
$InstallerFullpath=$AgentLocalfolder+"\"+$AgentFile

$Arguments =$Operators.Split("|")

foreach ($Argument in $Arguments){
Write-host "Argumnet $Argument" -ForegroundColor Cyan
$Argument=$Argument.trim()
$ArgumentList += "$Argument `n"
#$ArgumentList=@($ArgumentList)
Write-host "AgentName $AgentName
ListofServices $ListofServices
ArgumentList $ArgumentList " -ForegroundColor Green

 


$AgentInstall={

Write-Host "Installing $AgentName
Arguments $ArgumentDetails
Services $ListofServices"
Function Check-Service{

Param ($ServiceName)
Write-Host "checking $ServiceName "

try{
$Service = Get-Service -Name $ServiceName -ErrorAction stop
}
Catch { $_NoServiceFoundForGivenName
write-host "Still Waiting for the $ServiceName Service on the $VMName, I will try again shortly " -ForegroundColor Yellow
Start-Sleep -Seconds 5
write-host "I am trying $ServiceName Service on the $VMName " -ForegroundColor Yellow
}
if ($Service.Status -eq "Running")
{$Result = "PASS"
Write-Host "Service $ServiceName ......PASS" -ForegroundColor Green}
Else{$Result = "FAIL"
Write-Host "Service $ServiceName ......FAIL" -ForegroundColor Red}
Return $Result
}

#Install Agents

Start-Process "msiexec.exe" -Wait -ArgumentList (,$ArgumentDetails) -Verb runas

Start-Sleep -Seconds 140
$AgentCounter= [int] "0"
foreach($Agentservice in $ListofServices){
do {$Status= Check-Service -ServiceName $Agentservice
Write-Host "waiting Status....."
if ($Status -eq "FAIL") {$AgentCounter ++
Start-Sleep -Seconds 2 }
write-host "$AgentCounter" -ForegroundColor Yellow

if ($AgentCounter -eq "240") {write-host "Serivce $AgentName took a long time to Respond " -ForegroundColor Yellow
Send-eMail -MessageType Failure -MessageContent "Serivce $AgentName took a long time to respond on $VMName"
Stop-Process -Name powershell -Force}
}until ($Status -eq "PASS")
Write-Host "waiting....."
}

Start-Sleep -Seconds 20
}
Invoke-VMScript -vm $vmname -ScriptText $AgentInstall -GuestCredential $WinodwsLocalCredentials -Server $vCentre -ScriptType Powershell -Verbose


Write-Host "Installing $AgentName
Arguments $ArgumentList
Services $ListofServices" -ForegroundColor Yellow

}
}

 

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The value on the ScriptText parameter of the Invoke-VMScript cmdlet has to be a String, not a Codeblock.


If you want to pass values to the code to be executed by Invoke-VMSCript, you will have to incorporate those in that String.
One way of doing that is by using the ExpandString method.

See some samples of that method in my Here strings and the ExpandString method dive.

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
7 Replies
LucD
Leadership
Leadership
Jump to solution

The value on the ScriptText parameter of the Invoke-VMScript cmdlet has to be a String, not a Codeblock.


If you want to pass values to the code to be executed by Invoke-VMSCript, you will have to incorporate those in that String.
One way of doing that is by using the ExpandString method.

See some samples of that method in my Here strings and the ExpandString method dive.

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
AymanSammour
Contributor
Contributor
Jump to solution

thank you for your feedback,
I have followed your chain of thought and changed the datatype of the parameters from array to strings. but when I check inside the scriptblock if the string is null or has empty values, the statement comeback true

 


Write-Host "Arguments is $ArgumentString "
if ([String]::IsNullOrWhiteSpace($ArgumentString)){Write-Host "Arguments list is empty"}

 

-----------------------------------------------------------------------------------------------------------------------| Installing
| Arguments
| Services
|
| Arguments is
| Arguments list is empty
| Start-Process : Cannot validate argument on parameter 'ArgumentList'. The argument is null, empty, or an element of
| the argument collection contains a null value. Supply a collection that does not contain any null values and then try
| the command again.
| At line:34 char:49
| + ... -Process "msiexec.exe" -Wait -ArgumentList (,$ArgumentString) -Verb ...
| + ~~~~~~~~~~~~~~~~~~
| + CategoryInfo : InvalidData: (:) [Start-Process], ParameterBindingValidationException
| + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.StartProcessCommand
|

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Since you didn't show what exactly you did, I can't say what you did wrong.

One common mistake is to use double quotes instead of single quotes for the here string.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
AymanSammour
Contributor
Contributor
Jump to solution

please see the code below, 

I am trying to pass 2 functions to push software to new vm, one function will check the services are up and running and the other will install agents with arguments.

foreach ($Agent in $WinoswsAgnetsList) {

$AgentName=$AgentFile= $ListofServices= $ArgumentList=$MSIArguments= $DataStamp=$logFile=$InstallerFullpath =$AgentDetails= $ArgumentString =$ServiceString=$null
write-host "Now processing $Agent"
$AgentDetails=Select-HashTable -Hashtable $loadVars -Include $Agent
Write-Host $AgentDetails
$AgentName =$AgentDetails.Keys
$AgentFile =$AgentDetails.values.AgentName
$ListofServices =$AgentDetails.values.ListofServices
$Operators =$AgentDetails.values.ArgumentList
$InstallerFullpath=$AgentLocalfolder+"\"+$AgentFile

if (-not([String]::IsNullOrWhiteSpace( $ListofServices))){

$ListofServices= $ListofServices.split(",")}

foreach($Service in $ListofServices){
Write-host "Service $ListofServices" -ForegroundColor Cyan
$Service=$Service.trim()

if ([String]::IsNullOrWhiteSpace($ServiceString)){
$ServiceString = $Service
}

else {$ServiceString = $ServiceString+ -join ","+$Service}
}

$Arguments =$Operators.Split("|")

foreach ($Argument in $Arguments){
Write-host "Argumnet $Argument" -ForegroundColor Cyan
$Argument=$Argument.trim()
if ([String]::IsNullOrWhiteSpace($ArgumentString)){
$ArgumentString = $Argument
}

else {$ArgumentString = $ArgumentString+ -join ","+$Argument}

}


Write-host "AgentName $AgentName
ListofServices $ListofServices
ArgumentList $ArgumentList " -ForegroundColor Green

 

$AgentInstall={

Function Check-Service{

Param ($ServiceName)
Write-Host "checking $ServiceName "

try{
$Service = Get-Service -Name $ServiceName -ErrorAction stop
}
Catch { $_NoServiceFoundForGivenName
write-host "Still Waiting for the $ServiceName Service on the $VMName, I will try again shortly " -ForegroundColor Yellow
Start-Sleep -Seconds 5
write-host "I am trying $ServiceName Service on the $VMName " -ForegroundColor Yellow
}
if ($Service.Status -eq "Running")
{$Result = "PASS"
Write-Host "Service $ServiceName ......PASS" -ForegroundColor Green}
Else{$Result = "FAIL"
Write-Host "Service $ServiceName ......FAIL" -ForegroundColor Red}
Return $Result
}

Function Install-Agent{
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$AgentName,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$AgentArgument,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$AgentsServicesNames)

$ArgumentList=@()

Write-Host "Agent Name is $AgentName"
#if ([String]::IsNullOrWhiteSpace($ArgumentString)){Write-Host "Arguments list is empty"}
$ArgumentString=$ArgumentString.split(",")
foreach ($Argu in $ArgumentString){
Write-host "Argumnet $Argument" -ForegroundColor Cyan
$ArgumentList += "$Argu `n" }
$ArgumentList=@($ArgumentList)

Start-Process "msiexec.exe" -Wait -ArgumentList ($ArgumentList) -Verb runas

#Start-Sleep -Seconds 140
$ListofServices=$ServiceString.split(",")
$AgentCounter= [int] "0"
foreach($Agentservice in $ListofServices){
do {$Status= Check-Service -ServiceName $Agentservice
Write-Host "waiting Status....."
if ($Status -eq "FAIL") {$AgentCounter ++
Start-Sleep -Seconds 2 }
write-host "$AgentCounter" -ForegroundColor Yellow

if ($AgentCounter -eq "240") {write-host "Serivce $AgentName took a long time to Respond " -ForegroundColor Yellow
Send-eMail -MessageType Failure -MessageContent "Serivce $AgentName took a long time to respond on $VMName"
Stop-Process -Name powershell -Force}
}until ($Status -eq "PASS")
Write-Host "waiting....."
}

Start-Sleep -Seconds 20

}

Install-Agent -AgentName $AgentName -AgentArgument $ArgumentString -AgentsServicesNames $ServiceString
#invoke-command -ComputerName $vmname -ScriptBlock {param ($AgentName) & $ServiceString} -ArgumentList $ArgumentList

}
Invoke-VMScript -vm $vmname -ScriptText $install -GuestCredential $WinodwsLocalCredentials -Server $vCentre -ScriptType Powershell -Verbose


Write-Host "Installing $AgentName
Arguments $ArgumentList
Services $ListofServices" -ForegroundColor Yellow

Start-Sleep -Seconds 20

}

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Not sure what you are trying to there.

The $AgentInstall variable is still a code block, which you don't seem to use in your code.
On Invoke-VMScript you use a variable $install, which is nowhere defined or initialised.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
AymanSammour
Contributor
Contributor
Jump to solution

yes you are right, I was trying to manipulate the scriptblock, even when i use the $AgentInstall  i am still having the same issue

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------| Install-Agent : Cannot validate argument on parameter 'AgentName'. The argument is null or empty. Provide an argument
| that is not null or empty, and then try the command again.
| At line:72 char:27
| + Install-Agent -AgentName $AgentName -AgentArgument $ArgumentString - ...
| + ~~~~~~~~~~
| + CategoryInfo : InvalidData: (:) [Install-Agent], ParameterBindingValidationException
| + FullyQualifiedErrorId : ParameterArgumentValidationError,Install-Agent

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I think I already mentioned that the value you pass to ScriptText can not be a code block, but needs to be a String.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos