Check connectivity on virtual machine in vCenter - powershell

I am trying to write a small powershell script that checks the health of a newly started server. Here's what I want to do:
Start VM if it's not already started
Wait for Guest Tools to start running
Run the powershell script Test-Connection MyDCServer -Quiet using Invoke-VMScript
Act on whether the check return $true or not.
I have 1. and 2. donem but I am running into trouble on 3. All I get back from Invoke-VMScript is a string presenting the output from the script, when I really want the return value from the script that I invoked.
Is this possible?

I found the solution:
$result = Invoke-VMScript ...
$result.ScriptOutput
$result.ExitCode

Related

Call CSV Data and Startup VM's depending on State

I am very new to Powershell and I am wanting to write a script that will check the status of Virtual Machines i.e running or stopped, then when the host machine reboots depending on the status of the VM's pior the the reboot it will start them or keep them in a stopped state.
So far I have written a script that will auto start all the local VM's on the host machine on start-up, however sometimes we shutdown a VM for a reason and don't want it starting back up again.
I have started writing a script that captures all the VM's on a host and writes it to a CSV file:
Get-VM | select VMName, State, Uptime| Export-CSV D:\VM.csv -NoTypeInformation
This produces the VMName and the current state ie "Running" or "Off"
My plan is to have this script run via a task scheduler every 12hrs and on-start up have a ps1 script run and grab the VMName and State and depending on the data Start the VM if it was previosuly running, or keep it in a stopped state if the value was set to "off"
Is there an easy way to write this?
Thanks.
Maybe the following article is helpful to you:
Using Task Scheduler for PowerShell
You can find the documentation of VM PowerShell CMDLET at VM PowerShell cmdlet
So for example if you have CSV file (vmstatus.csv) with VM Name and VM Status like:
VMNAME,VMstatus,
vm1,1
vm2,0
vm3,1
then maybe you can restart VM where the status is zero
$statusresult = Import-Csv -path C:\temp\vmstatus.csv
foreach ($st in $statusresult){
if ($St.VMSTATUS -eq 0){
Start-VM -Name $st.VMNAME
}
}

Why process that terminated by script from PowerCli stuck in "suspended" mode

When I run a script trough PowerCLI after connecting to a VM, I get a strange behavior of some processes, I'm using the "Invoke-VMScript" command that is running an EXE file (compiled in .Net 4.5) that looks for running process and try to kill them.
For some reason some process doesn't get closed, and stuck in "Suspended" mode. When they stuck in this mode even if I tried to remove them from the task manager I get an error "The operation could not be complete, Access is denies."
I'm logged in with the Administrator user
The powershell script that I'm using is:
$executeCommand = "call D:\myCleaningProcess.exe $param1";
Invoke-VMScript -VM $vmName -GuestUser $vmUser -GuestPassword $vmPass -ScriptText $executeCommand
*When running manually the file "EXE" it's works as expected and the process get killed.
Anyone know why I get this strange behavior?
You need to use the -ScriptType Bat parameter when calling EXEs in this manner. See example 3 for reference: https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.powercli.cmdletref.doc%2FInvoke-VMScript.html

Check whether a RunspacePool is already open on a machine

I have a process that runs Powersell script on a VM. This script defines a RunspacePool on the VM and sets threshold (no. of Runspaces) based on the resource capability of that VM. This process is recurring so I do not want it to keep defining and opening RunspacePools when there is already one defined and opened on that VM
At the beginning of the Powershell script, I have tried to check whether a Runspacepool is already defined\ opened by calling RunspacePoolStateInfo or RunspacePoolAvailability properties. But these are not identified as the Runspacepool object itself is not available in the new window that the process opens up to run the script
I am basically looking for a way to identify that a RunspacePool is open on a VM by using Powershell scripting
Answer for PowerShell V5 and newer
You can get the Runspacess in the current processes by running
Get-Runspace
or if you know the name
Get-Runspace -Name <name>
Remote Runspaces in PowerShell V5
If the Runspace you want to check is in another process, you must first do this.
Enter-PSHostProcess -Id <int>
or
Enter-PSHostProcess -Process <ProcessObject>

Unable to get required information from remote machines using powershell invoke-command

I am developing a tool which uses powershell script to search for new windows updates for the machine. Currently by using the 'invoke-command' i am remotely accessing the various build controllers,virtual machines and hosts and running this powershell script. But invoke-command is unable to fetch the update details every time whenever it is executed.
the usage of invoke-command as follows:
invoke-command -computername buildcontroller1 -filepath searchupdates.ps1 -credential $myceredential
if i run this command, 1st time i will get the output, but when again if i run this command after 2 to 3 hours or after 1 day,its not retrieving the update details.
can anyone please tel me the reason for this.
I cannot tell you the reason for this.
I suspect the reason for needing to ask is an absence of error handling in the searchupdates.ps1 script.

powershell v2 remote features?

Just listened to Hansellminutes podcast. He had a talk with two Microsoft PS developers. They mentioned PS V2 remoting features.
I have some scripts based on PS v1. In terms of remoting commands or executions, I installed PS on local and a remote machines. Then I use PsExec.exe to push bat on remote to execute PS scripts. Now I am thinking to take advantage of PS V2.
To simple questions I have, to get a list of files on local, I can use the following codes:
$fs = Get-Item -Path $Path | Where { !$_.PSIsContainer ... } # more constrains in ...
if ( $fs -ne $null )
{
# continue to work on each file in the collection
...
}
What is the equivalent command to get a collection of files from a remote? I prefer to get a similar collection of file objects back so that I can access to their properties.
The second question is how to exec a command on remote with external application? I tried to use WIM Process before, but I could not get WMI class working on a case of Windows 2008 server. Then I used PsExec.exe to push a bat to a remote to execute PS script. It works in the cases. However, the problem I have to install PS on the remote as well. I am going to working another remote. I'll try to avoid to install PS on the remote. Can I take PS V2 advantage to execute a command on a remote Windows? What's the new commands?
By the way, normally, I have to pass user name and pwd to a remote. I guess in PS I have to pass user/pwd as well.
You can either put your code above in a script file and invoke it on a remote computer using V2 remoting like so:
PS> Invoke-Command remotePCName -file c:\myscript.ps1
You will need to be running with admin privs (elevated if UAC enabled) in order to use remoting. The command above will copy the script to the remote machine, execute it and return deserialized objects. These objects are essentially property bags. They are not "live" objects and setting properties on them like IsReadOnly will not affect the remote file. If you want to set properties then do it in your script that executes on the remote PC.
The option if you have a little bit of script is to use a scriptblock like so:
PS> Invoke-Command remotePCName { Get-Item C:\*.txt | Where {$_.IsReadOnly }
You can execute native commands (EXE) on the remote computer in either script or a scriptblock. You only need to make sure the EXE is available on the remote PC.
Regarding credentials, if you're on a domain and you have admin privs on the remote computer you won't need to pass credentials as your default credentials should work. If you need to run as a specific user then use the -Credential parameter on Invoke-Command like so:
PS> $cred = Get-Credential
PS> icm remotePCName { gci c:\windows\system32 -r *.sys } -credential $cred
Regarding your last comment, no PowerShell will use Windows integrated security so you should not have to pass any username or password unless you wanted to run it as a different user.
If you haven't yet enabled PS remoting, every time I've tried I've had to actually turn off UAC while I was enabling remoting (then I could re-enable UAC once remoting was enabled). Running Enable-PSRemoting from an elevated command prompt was not enough and the error message was not at all useful.
EDIT: I've just confirmed in a fresh Windows 7 VM that this is not an issue. It could have been a beta issue that I am no longer experiencing as I've been using beta/rc/ctp of PowerShell and Windows 7 for a long time.