Reputation: 9
How do I write a PowerShell 4.0 script to return the virtualization vs. physical status of Windows 2003, 2008 and 2012 servers? I want to know if these servers are virtual. I want to run the script on a central Windows server. The script will interact with remote servers. I know of a PowerShell command to run on individual servers that will tell me. But I want it to check many remote servers at a time. Here is my basic (not-yet-working) script for one server, but it isn't working:
$ComputerName = "greatServer"
$UserName = "greatServer\jdoe"
$Password = Get-Content C:\Users\jdoe\Documents\password.txt
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName , $Password
Get-WmiObject -Query "select * from win32_computersystem"
Here is the error that I get:
New-Object : Cannot find an overload for "PSCredential" and the argument count: "2".
At C:\Users\jdoe\Documents.pass.ps1:4 char:15 + $Credential = New-Object -TypeName System.Management.Automation.PSCredential -Ar ...+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo InvalidOperation: (:) [New-Object], MethodException + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
The final query will have to be modified with a remove * and a comparison operation. The manufacturer in the results will indicate if it is a VMware, Hyper-V or physical server (e.g., Dell). I don't need help with modifying the final query. The select * will work assuming it can work on remote servers.
I really want help with the error that I am getting. I have written a working script, but it requires a user to enter the password manually. I just want help to make the script non-interactive (and suppress the prompt). I have been unsuccessful with passing a password argument to get around the interactive password entry requirement.
Does the file that holds that password need to be encrypted? Will this work on remote servers that are Windows Server 2003? I reviewed other scripts I found online. The "cat C:\password.txt" portion didn't seem to work for me. I tried the convertTo-string and securestring options. Both those caused errors too.
Upvotes: 0
Views: 1592
Reputation: 3341
A better way is to store the credential securely. You will need to do this using the same user that will run the script (which means you might have to log on to that server as the serviceaccount which will run the script).
Anyway, from there you can do:
$cred = get-credential # Type in the greatserver credential
$cred | Export-Clixml -Path .\cred.xml
In your script you can now load the credential simply by running
$cred = Import-Clixml -Path .\cred.xml
This is the recommended way of persisting credentials to disk. Obviously, if you require a unique credential for each server you want to query this wouldn't work so well - you'd be better off using a domain account which is an administrator on all your servers (provided that your servers are actually joined to a domain).
Upvotes: 2
Reputation: 13537
Check out this script from the Technet Script repository, it pretty much does precisely what you need to do already.
The key to determining if a machine is virtual or not is to query the Win32_Bios and Win32_ComputerSystem classes to to check for Bios.Serial and ComputerSystem.Model and Manufacturer.
The way that the script works is to get the results of these queries then check to see if the Serial number field contains VMware, Xen, Microsoft or something else.
It's a lot of work to go creating a tool like this on your own since you'd need to research what to expect for various fields like bios, manufacturer and model and do some heavy lifting with scripts to get the right answer; I'd highly recommend you use this function instead.
Upvotes: 0