Thursday, September 29, 2011

How to Enable Powershell Remoting using VMware invoke-vmscript

Enabling Powershell remoting using scripting can be tricky due to permissions issues. One work-around is to use the task scheduler to invoke the script locally. Another method I have used is to enable remoting using VMware’s PowerCLI—obviously this will only work for Windows guests running on VMware with functioning tools.
The script is very simple:
$guestcred=get-credential
$hostcred=get-credential
$script = 'Enable-PsRemoting –F'
$vms = get-vm | where {$_.PowerState -eq "PoweredOn" -and $_.Guest.OSFullName -match "Microsoft Windows*" } | Sort Name
foreach($vm in $vms){invoke-vmscript -scripttext $script -vm $vm  -guestcredential $guestcred -hostcredential $hostcred}
The first two lines get the guest and host credentials that will be used to launch the script. The host credentials are usually the actual root account on the host—not the credentials for vCenter. The script that needs to be executed in each guest is stored in the $script variable.
The VMs to run the script on are then collected. I am limiting it to only Windows guests that are in a powered on state.
Finally I run the script inside each guest using a foreach loop. It is possible to pass in an array of VMs, but I have found that if you have a heavy consolidation ratio it can cause dramatic CPU spikes.
You can then test your connections using enter-pssession or invoke-command.

Wednesday, September 21, 2011

Powershell PSComputerName is empty or blank when selected after invoke-command

When using PowerShell remoting a NoteProperty object is attached to each result to indicate the computer the result was generate on.  This property is empty or blank when a select object is done further down the pipeline, but inspecting the object shows the data is present.  Here is an example:
invoke-command -computername MyServer -scriptblock {gwmi win32_operatingsystem}
SystemDirectory : C:\WINDOWS\system32
Organization    : IT
BuildNumber     : 3790
RegisteredUser  : User
SerialNumber    : 69713-640-2887872-45140
Version         : 5.2.3790
PSComputerName  : MyServer

invoke-command -computername MyServer -scriptblock {gwmi win32_operatingsystem} | Select PSComputerName, Version
Version
-------
5.2.3790

A simple way to work around this problem is to use the format-table cmdlet:
invoke-command -computername MyServer -scriptblock {gwmi win32_operatingsystem} | Format-Table PSComputerName, Version
PSComputerName                                                                                      Version
--------------                                                                                      -------
MyServer                                                                                            5.2.3790

Saturday, September 17, 2011

Enabling Powershell Remoting on Remote Computers

Powershell remoting is a powerful tool that allows you to run a powershell session on a remote computer. Enabling remoting on a single computer is simple:

Start a powershell.exe prompt (Run as administrator after XP/2003)
Type: Enable-PsRemoting -F

If you have hundreds of computers you want to enable it on it is more difficult. Psexec will hang when executing the command which prevents the standard administrator method. There are some complex scripts floating around the internet. I found the following method to be very simple:

schtasks /create /s servername /rl highest /ru SYSTEM /sc once /st 18:00 /TN EnableRemoting /TR "powershell -noprofile -command Enable-PsRemoting -F" /F /Z /V1

Change the /s servername to the actual server name
Change /st time to a time in the future (be careful if you have servers in different time zones)

After the task runs, the /Z parameter will cause it to be deleted automatically.

If you do not use the /V1 parameter when scheduling a task against a 2003 server you will receive the following error:

ERROR: The task XML contains a value which is incorrectly formatted or out of range.

To execute the schtasks command against a large number of servers, you can use a text file with the server names and a for loop:

for /f %i in (textfile.txt) do schtasks /create /s %i /rl highest /ru SYSTEM /sc once /st 18:00 /TN EnableRemoting /TR "powershell -noprofile -command Enable-PsRemoting -F" /F /Z /V1

To test your work start powershell:
invoke-command -computername remotecomputername -scriptblock {hostname}