Archive

Posts Tagged ‘Scripting’

Installing VMware SDK with Visual Studio 2010 / Visual Studio 2010 Express – workaround

March 31, 2011 Leave a comment

This is just a quick workaround to get the installation done – nothing else (really a reminder to myself)

I have a project to provision VMs from a customised front-end,
I have created a C# tool – that integrates with SCCM as well as our various asset management tools and some scripting environments, to allow for a ‘1 button deployment’

Of course . . to be a true one button deployment, I’d like to be able to actually create a VM when using the same ‘Big Red Button’

Anyway, my development environment happens to be Visual Studio 2010 – so yes simple . . let’s get going, surely we just follow the setup guide provided at :

http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/sdk40setupguide.pdf – page 19

Well, that would work, except that the SDK kit has not yet gotten the relevant batch files for a Visual Studio 2010 installation.

The solution to get the installation working was to get a copy of the amended cmd from the VMWare communities:
http://communities.vmware.com/servlet/JiveServlet/download/1225636-21465/genvimstubs2.cmd
and copy it to your .\sdk\samples\DotNet directory

Next, go to : Start Menu\Programs\Microsoft Visual Studio 2010\Visual Studio Tools and select Visual Studio Command Prompt (2010)

Now, make sure that you have the environmental variable VCINSTALLDIR set to point to your Visual Studio installation path (type ‘set’ to see your environmental variables)
I had to set it like this:

SET VSINSTALLDIR="c:\Program Files (x86)\Microsoft Visual Studio 10.0"

Finally, I had to run the installer.]
In my case, the SDK was at d:\VMWare\SDK\samples, so I ran:

D:\VMWare\SDK\samples\DotNet>genvimstubs2.cmd d:\VMWare\SDK\wsdl\vim25 Vim25Api stage Vim25Objects.cs . Vim25Service2005

Installation looks like this:

D:\VMWare\SDK\samples\DotNet>genvimstubs2.cmd d:\VMWare\SDK\wsdl\vim25 Vim25Api
stage Vim25Objects.cs . Vim25Service2005
Checking and Creating stage
The system cannot find the file specified.
Microsoft (R) Web Services Description Language Utility
[Microsoft (R) .NET Framework, Version
2.0.50727.1432]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file ‘stage\Vim25Objects.cs’.
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.4926
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.

Microsoft (R) Xml Serialization support utility
[Microsoft (R) .NET Framework, Version
2.0.50727.1432]
Copyright (C) Microsoft Corporation. All rights reserved.
Serialization Assembly Name: Vim25Service2005.XmlSerializers, Version=0.0.0.0, C
ulture=neutral, PublicKeyToken=null.
Generated serialization assembly for assembly D:\VMWare\SDK\samples\DotNet\vim25
service2005.dll –> ‘.\Vim25Service2005.XmlSerializers.dll’.
Optimizing generated stubs…
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.4926
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.

Stub generation Done.
ECHO is off.

From here you can continue using the instructions in the getting started guide above.

Categories: Scripting, VMWare Tags: ,

Function : Get-Function

February 24, 2011 Leave a comment

Here’s a time saver… well a quick function that has saved me a whole herd of time when trying to find a function that has been “forgotten”

Function Get-Function ($searchterm,[switch]$DEFINITION)
{
	$functions = @(Get-Command "*$searchterm*" -CommandType "Function")
	"`nFunctions matching ""$searchterm""`n" | Write-Host -ForegroundColor Green
	if (!$DEFINITION) {$functions | %{$_.name}} else {$functions | %{"`n$($_.name)" | Write-Host -f Yellow ;$_.definition}}
}

sal gf Get-Function

the last line is setting an alias “gf”
– so let’s try this on something familiar… we had a function searching for apps…

Command: gf apps
Output:
Functions matching “apps”
Get-Apps
Get-CoreApps
Get-InstalledApps
Set-InfsApps

Ahh – “installed apps”, let’s try that one again, and get Details this time:

Command: gf installedapps -de
Output:
Functions matching “installedapps”
Get-InstalledApps
param (
$computername=$env:computername,
$regkey_x64 = “SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”,
$regkey_x86 = “SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall”,
[switch]$DISPLAY,
[switch]$EXCLUDE32,
[switch]$EXCLUDE64
)
$bits_to_search = @()
if (!$EXCLUDE32){$bits_to_search += “x86”}
if (!$EXCLUDE64){$bits_to_search += “x64”}

$apps = @()
foreach ($bit in $bits_to_search)
{
$regkey = Get-Variable “regkey_$bit” | %{$_.value}
if (Test-Path HKLM:$regkey)
{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(“LocalMachine”,$computername)
$key = $reg.OpenSubKey($regkey)
$SubKeys = $key.GetSubKeyNames() | %{$key.OpenSubKey($_)}

foreach ($subkey in $subkeys)
{
$app = $subkey | select @{N=”Bit”;E={$bit}},`
@{N=”Name”;E={$_.getvalue(‘DisplayName’)}},`
@{N=”Version”;E={$_.GetValue(‘DisplayVersion’)}},`
@{N=”Publisher”;E={$_.GetValue(‘Publisher’)}}
if ($app.name) {$apps += $app}
}
}
$key.Close()
$reg.Close()
}

# Remove duplicates, but annoyingly names like of “C++” error when using “-match”
$unique_apps = @()
foreach ($app in $apps)
{
if (!($unique_apps | ?{$_.Bit -eq $app.bit} | ?{$_.name -eq $app.name} |
?{$_.version -eq $app.version})) {$unique_apps += $app}
}

return $unique_apps | sort bit,name,version

Comparing IPs using Powershell – Script of the Day

February 21, 2011 Leave a comment

Ever needed to script around IP addressing issues on hosts and needed to determine whether 2 hosts are in fact on the same subnet or not?

Try the following Function


Function Compare-Subnets {
param (
[parameter(Mandatory=$true)]
[Net.IPAddress]
$ip1,

[parameter(Mandatory=$true)]
[Net.IPAddress]
$ip2,

[parameter()]
[alias("SubnetMask")]
[Net.IPAddress]
$mask ="255.255.255.0"
)

if (($ip1.address -band $mask.address) -eq ($ip2.address -band $mask.address)) {$true}
else {$false}

}

The code simply does a binary comparison of the 2 IP addresses.

– much like you used to do when you first did TCPIP subnetting (some of you may remember this)

To use it, the syntax is simply as follows

Compare-Subnets -IP1 $IP1 -IP2 $IP2 -mask $SubnetMask

and the return is simply a boolean True or False. – Simple

e.g.PS:115 >Compare-Subnets -ip1 10.2.208.151 -ip2 10.2.208.251 -mask 255.255.255.240
False

Function : Get-InstalledApps

February 16, 2011 Leave a comment

So there I was happily using

gwmi win32_product 

to get me a list of installed applications, but this is slow, and often we just want a quick verification that an application is installed or not.

Thanks to powershell.com and their “PowerTip of the Day” I was reminded about hitting the registry for this information…
So, inspired by their code, I hacked together a quick function to do this.

Note the removal of duplicates was first done as per the concept here Script of the Day – remove duplicate lines in a CSV file but there were a few entries with special characters in their names, eg “C++” that don’t play nicely with “-match” so this was recoded comparing each entry of the object. This is going to be slower, but still solves the “Get Installed Applications” faster than the WMI route!

Function Get-InstalledApps 
{
	param (
		$computername=$env:computername,
		$regkey_x86 = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
		$regkey_x64 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
		[switch]$DISPLAY
		)

	$apps = @()	
	foreach ($bit in "x86","x64")
	{	
		$regkey = Get-Variable "regkey_$bit" | %{$_.value}
		if (Test-Path HKLM:$regkey)
		{
			$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$computername)
			$key = $reg.OpenSubKey($regkey)
			$SubKeys = $key.GetSubKeyNames() | %{$key.OpenSubKey($_)}
	
			foreach ($subkey in $subkeys)
			{
				$app = $subkey | select @{N="Bit";E={$bit}},`
										@{N="Name";E={$_.getvalue('DisplayName')}},`
										@{N="Version";E={$_.GetValue('DisplayVersion')}},`
										@{N="Publisher";E={$_.GetValue('Publisher')}}
				if ($app.name) {$apps += $app}
				}
			}
		    $key.Close()
		    $reg.Close()
		}
   
	# Remove duplicates, but annoyingly names like of "C++" error when using "-match"
	$unique_apps = @()
	foreach ($app in $apps) 
	{
		if (!($unique_apps | ?{$_.Bit -eq $app.bit} | ?{$_.name -eq $app.name} | 
		?{$_.version -eq $app.version})) {$unique_apps += $app}
	}

return $unique_apps | sort bit,name,version
}

Script of the Day – Creating AD groups without QAD cmdlets

February 10, 2011 1 comment

We’re automating some server builds and need to create AD groups to manage resource access to each Server (company policy)
We use SCCM for deployment and I wanted to automate the groups (at build time)
Also, I did not want to have any dependencies on external Modules (so I want to do this without the quest tools)

I found a few documents online for creating AD groups that went without the quest tools, but found that most did not work.

You see, our key problem was that we wwanted to create Domain Local Security Groups.
In VBScript, this was pretty simple, as on the ‘put’ portion of group creation, you just told the script to apply both Group type constants, using an or statement.
The theory was that this would work in Powershell too (and many online script seemed to indicate that it would) – but the group types being created were inconsistent.

Below are the constants for the different group types:

Value GroupType
2 Global distribution group
4 Domain local distribution group
8 Universal distribution group
-2147483646 Global security group
-2147483644 Domain local security group
-2147483640 Universal security group

So creating a Domain Local Security group is as simple as:

$groupType = -2147483644
$objOU = [ADSI]"LDAP://localhost:389/OU=YourOUName,DC=Example,DC=com"
$GroupName = "MyNewGroup"
$objGroup = $objOU.Create("group", "CN=" + $GroupName)
$objGroup.Put("groupType", $groupType )
$objGroup.Put("sAMAccountName", $GroupName )
$objGroup.SetInfo()

Of course you can change the LDAP binding to a DC (rather than localhost) and you can change the GroupType by amending the value of $GroupType
Even better, you could wrap it into a Function, with a switch statement to take care of Group type selection.

Happy days.

Script of the Day – shutdown your VMware ESX estate with PowerCLI

February 7, 2011 Leave a comment

The following script is straight from
http://www.virtu-al.net/2010/01/06/powercli-shutdown-your-virtual-infrastructure/

I have used it a few times and it is very effective and easy to use.


Connect-VIServer MyVIServer

# Get All the ESX Hosts
$ESXSRV = Get-VMHost

# For each of the VMs on the ESX hosts
Foreach ($VM in ($ESXSRV | Get-VM)){
# Shutdown the guest cleanly
$VM | Shutdown-VMGuest -Confirm:$false
}

# Set the amount of time to wait before assuming the remaining powered on guests are stuck
$waittime = 200 #Seconds

$Time = (Get-Date).TimeofDay
do {
# Wait for the VMs to be Shutdown cleanly
sleep 1.0
$timeleft = $waittime - ($Newtime.seconds)
$numvms = ($ESXSRV | Get-VM | Where { $_.PowerState -eq "poweredOn"}).Count
Write "Waiting for shutdown of $numvms VMs or until $timeleft seconds"
$Newtime = (Get-Date).TimeofDay - $Time
} until ((@($ESXSRV | Get-VM | Where { $_.PowerState -eq "poweredOn" }).Count) -eq 0 -or ($Newtime).Seconds -ge $waittime)

# Shutdown the ESX Hosts
$ESXSRV | Foreach {Get-View $_.ID} | Foreach {$_.ShutdownHost_Task($TRUE)}

Write-Host "Shutdown Complete"

BE WARNED – IF YOU TEST THIS ON YOUR LIVE ENVIRONEMT, YOU’RE GOING TO GET IN TROUBLE!!!!

Script of the Day – changing ESX NTP servers

February 2, 2011 Leave a comment

The following script will amend the NTP server settings for all ESX hosts in your VC

$ntp1 = <ipaddress>"
$ntp2 = "<ipaddress>"
$oldntp = "<ipaddress>"
$oldntp2 = "<ipaddress>"

Add-PSSnapin VMware.VimAutomation.Core
connect-viserver -server &lt;vcentername&gt; -credential (Get-Credential)

$vmhosts = Get-VMHost

foreach ($element in $vmhosts)
{
Remove-VMHostNtpServer -NtpServer $oldntp -VMHost $element
Remove-VMHostNtpServer -NtpServer $oldntp2 -VMHost $element
Add-VmHostNtpServer -NtpServer $ntp1 -VMHost $element
Add-VmHostNtpServer -NtpServer $ntp2 -vmhost $element

$ntpd = Get-Vmhostservice -VMHost $element | where {$_.key -eq 'ntpd'}
Restart-VMHostService $ntpd -Confirm:$false
}