Hello,
I'm trying to create a script that will run the Get-Service command on a VM. If I just want to look at all services that's rather easy by having this in the script:
$script = "Get-Service -Name *"
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
With all the other proper stuff, like VM name, guest credentials, etc. However that can be a huge list and I want to have an option to select either running or stopped services as well. I notice when I run this command on my local machine it works properly:
Get-Service | ?{$_.Status -like 'Running'}
But when I put that into the $script line above and run it on a VM it throws this:
.Status : The term '.Status' 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.
At line:1 char:20
+ & {Get-Service | ?{.Status -like 'Running'}}
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (.Status:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
So I'm not quite sure why it fails like that when running on a VM. Here's what I have in the script:
Get-Datacenter -Name $dc[$answer - 1].Name | Get-Folder -Type "VM" | sort Name | Format-Table
$myfolder = Read-Host "Select a folder"
Get-Folder "$myfolder" | Get-VM | sort Name | Format-Table
$vm = Read-Host "Enter VM Name" #Enter VM name#
$log = Read-Host "Enter a log file name i.e. services.txt"
$GuestCredential = Get-Credential -Message 'Enter the credentials to access the VM' #Provide Guest OS credentials
$servicesanswer = 0
Write-Host "1 for started services"
Write-Host "2 for stopped services"
Write-Host "3 for all services"
while(1,2,3 -notcontains $servicesanswer) {
$servicesanswer = Read-Host "Select the services you wish to view"
}
if($servicesanswer -eq 1){
$script = "Get-Service | ?{$_.Status -like Running}"
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
elseif($serviceanswer -eq 2){
$script = "Get-Service | ?{$_.Status -like Stopped}"
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
elseif($serviceanswer -eq 3){
$script = "Get-Service -Name *"
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
I had also noticed when I would select option 2 or 3 it would go to the loop at the end of the script and want to start over or exit. I've tried changing those elseif's to just 'if' but that didn't make a difference either. What am I missing here?
The reason for the failure is variable substitution inside a double-quoted string.
PS will replace variables in a double-quoted string with the value in the variable.
But since $_ is $null on the side where you run the script, this will result in a string with "Get-Service | ?{.Status -like Running}" being sent with the Invoke-VMScript cmdlet.
inside single quoted strings, that variable substitution will not happen.
So replace that line with
$script = 'Get-Service | ?{$_.Status -like Running}'
and the line of code will transferred to the guest OS of the VM as you intended.
Similar solution for the other commands that contain a $.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
So when I just did what you had shown without any quotes around the Running part it still threw an error. If I put " " around Running and single quotes around the rest it works, but only for option one. Option 2 or 3 never run and I don't understand why. Here's what I have now:
while(1,2,3 -notcontains $servicesanswer) {
$servicesanswer = Read-Host "Select the services you wish to view"
}
if($servicesanswer -eq 1){
$script = 'Get-Service | ?{$_.Status -like "Running"}'
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
elseif($serviceanswer -eq 2){
$script = 'Get-Service | ?{$_.Status -like "Stopped"}'
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
elseif($serviceanswer -eq 3){
$script = "Get-Service -Name *"
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
It basically skips the last 2 options when I try to run them and goes to the loop on if I want to continue the script or exit it. I've tried changing elseif to just if, but no change.
Your variable for option 2 and 3 is not correct, it should say $servicesanswer instead of $serviceanswer
if($servicesanswer -eq 1){
$script = 'Get-Service | ?{$_.Status -like "Running"}'
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
elseif($servicesanswer -eq 2){
$script = 'Get-Service | ?{$_.Status -like "Stopped"}'
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
elseif($servicesanswer -eq 3){
$script = "Get-Service -Name *"
Invoke-VMScript -vm $vm -ScriptText $script -ScriptType PowerShell -GuestCredential $GuestCredential | sort Name | Format-List | Out-File $log -append
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference