Tuesday, February 15, 2011

Get / Determine / Check your ESX version, major version or build version

To check your esx version, use in command line:


vmware -v
return for example in a 3.0.1 ESX
VMware ESX Server 3.0.1 build-32039

vmware -v
return for example in a 3.5 ESX
VMware ESX Server 3.5.0 build-238493

vmware -v
return for example in a 4.1 ESX
VMware ESX 4.1.0 build-260247



But If you need to know only version use

vmware -v | awk -F "uild" '{print $1}' | sed -e 's/[A-Za-z ]//g'

return in our 3 examples
3.0.1
3.5.0
4.1.0


In your script you can use this information into a variable

ESX_VERSION=`vmware -v | awk -F "uild" '{print $1}' | sed -e 's/[A-Za-z ]//g'`
echo $ESX_VERSION

return in our 3 examples
3.0.1
3.5.0
4.1.0




To know major version only

vmware -v | awk -F "uild" '{print $1}' | sed -e 's/[A-Za-z ]//g' | cut '-d.' -f1

return in our 3 examples
3
3
4


To know major and minor version only

vmware -v | awk -F "uild" '{print $1}' | sed -e 's/[A-Za-z ]//g' | awk -F "." '{print $1"."$2}'

return in our 3 examples
3.0
3.5
4.1


If you need to know build only

vmware -v | awk -F "uild-" '{print $2}'

return in our 3 examples
32039
238493
260247

Wednesday, February 9, 2011

Powershell to help you to sort, manipulate or consolidate CSV file

To help you to sort, manipulate or consolidate your information, Powershell is a very interesting tool.

First, you need a .csv file with this format (use excel file save as)


col1,col2,col3
c,cc,ccc
a,aa,aaa
b,bb,bbb
c,cc,ccc
b,bb,bbb


For example, to select only one column, just use colum name

Import-Csv .\test.csv | select col2



col2
----
cc
aa
bb
cc
bb


If your .CSV has ";" and not "," as delimiter you can change this by adding -Delimiter switch like that


Import-Csv .\test.csv -Delimiter ";" | select col2

(Warning: This switch does not work on Powershell 1.0)

Moreover, be sure to have a header else you will have a error
Import-Csv : The member "xxxx" is already present
And do not forget # is considered as a remark

Now, if you only need distinct col2 use -unique switch and Sort-object if you need to have only distinct field

Import-Csv .\test.csv | select -unique col2 | Sort-Object col2



col2
----
aa
bb
cc


To display each line with column 3 then column 1 then column 2 you can do like this

$content = import-csv ".\test.csv"
foreach ($line in $content) {
write-host $line.col3 $line.col2 $line.col1
}


result:

ccc c cc
aaa a aa
bbb b bb
ccc c cc
bbb b bb


or like this:

Import-Csv .\test.csv | select col3, col1, col2


result:

col3 col1 col2
---- ---- ----
ccc c cc
aaa a aa
bbb b bb
ccc c cc
bbb b bb


Or like this:

$Content = Get-Content ".\test.csv"
$arrLine = @( )
Foreach ($line in $Content) {
$line =$line.Trim()
If ($line.length -gt 0) {
$arrLine=$line.split(",")
write-host $arrLine[2] $arrLine[0] $arrLine[1]
}
}


result:

col3 col1 col2
ccc c cc
aaa a aa
bbb b bb
ccc c cc
bbb b bb

Tuesday, January 25, 2011

Register all VM to a new ESX host

A standalone ESX has been reinstalled. All VM are on a shared storage.
I registered all VM with this following command:


find /vmfs/volumes -name "*.vmx" | xargs -i{} vmware-cmd -s register {}


For information, you can replace xargs -I{} by xargs -i{} for certain esx version

Friday, January 14, 2011

HP Virtual Connect Blank page problem

Some elements of your HP Virtual Connect didn't work anymore like "Ethernet Networks" ?
Do you have a blank page ?
If your are in a secure environment where only port 443 is opened, try to open port 80. It seems that flash player in some VC version only work on this port

Before (only port 443 opened)















After (Port 80 and 443 opened)

Monday, January 3, 2011

Unregister all VM in a ESX host

Problem with an old ESX v3.0.2. All VM have been stopped. I must unregister all VM from this ESX. So I use replace-str xargs option like this:

vmware-cmd -l | xargs -i{} vmware-cmd -s unregister {}


You can stop / start / suspend / reset all VM using the same tip:

vmware-cmd -l | xargs -i{} vmware-cmd {} stop
vmware-cmd -l | xargs -i{} vmware-cmd {} start
vmware-cmd -l | xargs -i{} vmware-cmd {} suspend
vmware-cmd -l | xargs -i{} vmware-cmd {} reset


For information, you can replace xargs -I{} by xargs -i{} for certain esx version

Thursday, December 23, 2010

Generate remote registry .reg file export with powershell

Why create a .reg file with powershell when regedit /e switch or file / export on regedit work without any problem ?
Well, just for fun, but this solution can be useful if you need to do this for 3000 computers.
Some others solution exist like for example psexec with regedit (or hacked regedit for gpo security problem), but c$ must exist (that's not always the case for security reasons)

And why export .reg ?
A .reg file is more easy to analyze or compare with another registry file because it is in a string format. And you can re-use it directly without use any other tool than regedit integrated windows tool (except if you can't run regedit on your computer)

[EDIT 2011-03-23]
A new version with bug correction in multistring format


You can download this powershell script here and to test it you can use this testfr.reg file

How to use this powershell script:
.\ExportRegistyToFile.ps1 'key_to_export' 'outputfile.txt'
for example if you want to test with my registry created with testfr.reg
.\ExportRegistyToFile.ps1 'HKEY_CURRENT_USER\Software\TestFr' 'output_testfr.txt'




#
# Export registry to .reg file like regedit /e
#
# by F.Richard 2010-10
# Modified 2011-03 : bug correction in multistring format
#


# Working with Registry Entries
# http://technet.microsoft.com/en-us/library/dd315394.aspx

# [Enum]::GetNames([Microsoft.Win32.RegistryValueKind])
# -> Unknown / String / ExpandString / Binary / DWord / MultiString / QWord

# [Enum]::GetNames([Microsoft.Win32.RegistryHive])
# -> ClassesRoot / CurrentUser / LocalMachine / Users / PerformanceData / CurrentConfig / DynData

set-psdebug -strict

$debug = $True
#$debug = $False

$errorPref = "Continue" # "Continue" "Stop" "Inquire" "SilentlyContinue"
$ErrorActionPreference = $errorPref

# Script Directory
$strCurDir = Split-Path -parent $MyInvocation.MyCommand.Path
Set-Location $strCurDir | Out-Null

# ----------------------------

# DllImport using http://www.pinvoke.net
$signature = @"
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(HDEFKEY hKey, string subKey, int ulOptions, REGSAM samDesired, out UIntPtr hkResult);

[DllImport("advapi32.dll", SetLastError=true)]
public static extern int RegCloseKey(UIntPtr hKey);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueExW", SetLastError = true)]
public static extern int RegQueryValueEx(UIntPtr hKey, string lpValueName, int lpReserved, out uint lpType, System.Text.StringBuilder lpData, ref uint lpcbData);

[DllImport("advapi32.dll", EntryPoint = "RegEnumKeyEx")]
public static extern int RegEnumKeyEx(UIntPtr hKey, uint index, System.Text.StringBuilder lpName, ref uint lpcbName, IntPtr reserved, IntPtr lpClass, IntPtr lpcbClass, out long lpftLastWriteTime);

public enum REGSAM : int {
KEY_ALL_ACCESS = 0xF003F,
KEY_CREATE_LINK = 0x0020,
KEY_CREATE_SUB_KEY = 0x0004,
KEY_ENUMERATE_SUB_KEYS = 0x0008,
KEY_EXECUTE = 0x20019,
KEY_NOTIFY = 0x0010,
KEY_QUERY_VALUE = 0x0001,
KEY_READ = 0x20019,
KEY_SET_VALUE = 0x0002,
KEY_WOW64_32KEY = 0x0200,
KEY_WOW64_64KEY = 0x0100,
KEY_WRITE = 0x20006
}

public enum HDEFKEY : uint {
HKEY_CLASSES_ROOT = 0x80000000,
HKEY_CURRENT_USER = 0x80000001,
HKEY_LOCAL_MACHINE = 0x80000002,
HKEY_USERS = 0x80000003,
HKEY_CURRENT_CONFIG = 0x80000005,
HKEY_DYN_DATA = 0x80000006
}


"@

# Reg Val Types Declaration
# REG_NONE = 0 / REG_SZ = 1 / REG_EXPAND = 2 / REG_BINARY = 3 / REG_DWORD = 4 / REG_DWORD_BIG_ENDIAN = 5 / REG_LINK = 6
# REG_MULTI_SZ = 7 / REG_RESSOURCE_LIST = 8 / REG_FULL_RESSOURCE_DESCRIPTOR = 9 / REG_RESOURCE_REQUIREMENTS_LIST = 10 / REG_QWORD = 11

$RegValTypes = @{"0" = "Unknown"; "1" = "String"; "2" = "ExpandString"; "3" = "Binary";
"4" = "DWord"; "5" = "DWord_Big_Endian"; "6" = "Link"; "7" = "MultiString";
"8" = "Ressource_List"; "9" = "Full_Ressource_Descriptor"; "10" = "Ressource_Equirement_list"; "11" = "QWord"
}

# ----------------------------

Function transformBinReg {
Param(
[Ref] $ref_result_property,
[Ref] $ref_line,
[Ref] $ref_values,
[Int] $nb_values,
[Ref] $ref_comma,
[Ref] $ref_nb_bin,
[String] $multi
)
$ref_comma.value = $(if ($ref_comma.value) {$ref_comma.value} else {""})
$ref_nb_bin.value = $(if ($ref_nb_bin.value) {$ref_nb_bin.value} else {0})
$multi = $(if ($multi) {$multi} else {$False})

For ($i=0; $i -lt $nb_values; $i++) {
$ref_line.value = $ref_line.value + $ref_comma.value + ([String]::Format("{0:x2}", $ref_values.value[$i]))
$ref_nb_bin.value++
$ref_comma.value = ","
if (($ref_line.value.length -gt 75) -or ($ref_nb_bin.value -eq 25)) {
if (($result_property.length - $result_property.LastIndexOfAny("`r`n")) -gt 73) {
$ref_result_property.value = $ref_result_property.value + ",\`r`n "
}
$ref_result_property.value = $ref_result_property.value + $ref_line.value
If ($i -lt ($nb_values-1)) {
$ref_result_property.value = $ref_result_property.value + ",\`r`n "
}
$ref_comma.value = ""
$ref_line.value = ""
$ref_nb_bin.value=0
}
}

If ($multi -eq $True) {
if ($ref_nb_bin.value -eq 0) {
if ($ref_result_property.value.substring($ref_result_property.value.length - 5 , 5) -eq "2a,00" ) { # 00,\
$ref_result_property.value = $ref_result_property.value.substring(0,($ref_result_property.value.length-5)) + "00,00" # replace end string - "2a" by "00"
}
} elseif ($ref_nb_bin.value -eq 1) {
if ($ref_result_property.value.substring($ref_result_property.value.length - 8, 4) -eq "2a,\" ) { # 2a,\
$ref_result_property.value = $ref_result_property.value.substring(0,($ref_result_property.value.length-8)) + "00" + ",\`r`n " # replace end string - "2a" by "00"
}
} else {
$ref_line.value = $ref_line.value.substring(0,($ref_line.value.length-5)) + "00,00" # replace end string - "2a,00" by "00,00"
}
}
}


# ----------------------------

Function transformStringReg {
Param($strReg)

$result = $strReg -replace("\\", "\\") # replace \ by \\
$result = $result -replace('"', '\"')
return $result
}

# ----------------------------

Function ExportReg {
Param(
[String] $hiveKey,
[String] $registrypath,
[String] $Computername,
[String] $outputfile
)
$computerKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hiveKey, $Computername)
$Key = $computerKey.OpenSubKey($registrypath,$false)
If(!($Key)){Return}

$result = "[" + $Key.Name + "]" + "`r`n"
If ($debug) { Write-Host $result }
$SubKeyValues = $Key.GetValueNames()
foreach($SubKeyValue in $SubKeyValues) {
$propertyname = $SubKeyValue
$propertyvalue = $Key.GetValue($SubKeyValue)
$result_property = ""
$TypeNameOfValue = ""
If ($propertyname -eq "") {
$TypeNameOfValue = "(default)"
$hKey = New-Object UIntPtr
$keyname = $key.Name
$hKeyLeft = $keyname.Substring(0, $keyname.IndexOf('\'))
$hKeyRight = $keyname.Substring( ($keyname.IndexOf('\') + 1) , ($keyname.Length - $keyname.IndexOf('\') - 1) )
$result_func = [Win32Functions.Registry]::RegOpenKeyEx($hKeyLeft, $hKeyRight, 0, "KEY_READ", [ref] $hKey)
if ($result_func -eq 0) {
$valuename = "" # (default) = ""
$lpType = New-Object uint32
$lpData = New-Object System.Text.StringBuilder
$lpcbData = New-Object uint32
# Get Type & Size
$result_func = [Win32Functions.Registry]::RegQueryValueEx($hKey, $valuename, $Null, [ref] $lpType, $lpData, [ref] $lpcbData)
# ERROR_FILE_NOT_FOUND = 2 $result_func
$TypeNameOfValue = $RegValTypes["$lpType"]
}
$result_func = [Win32Functions.Registry]::RegCloseKey($hKey)
$result_name = "@"
$property_name = ""

} else {
$ErrorActionPreference = "Continue" #"SilentlyContinue"
$TypeNameOfValue = $key.GetValueKind($propertyname) # $property.TypeNameOfValue not so precise String = ExpandString too
If ($TypeNameOfValue -eq "") { # OpenSaveMRU\* problem
$TypeNameOfValue = "TrapError"
}
$ErrorActionPreference = $errorPref
$result_name = "`"" + $(transformStringReg($propertyname)) + "`""
$property_name = $propertyname
}

Switch ($TypeNameOfValue) {
# TrapError
"TrapError" {
$result_property = ""
} # End TrapError

# String "System.String"
"String" {
$result_val = transformStringReg($propertyvalue)
$result_property = $result_name + "=`"" + $result_val + "`""
} # end String

# ExpandString "System.String"
"ExpandString" {
$result_property = ""
$tmpvalues = ($key.GetValue($property_name,"error",[Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames))
$values = [System.Text.Encoding]::UNICODE.GetBytes($tmpvalues + "*") # * = 2a
$line = $result_name + "=hex(2):"
$comma = ""
$nb_bin = 0
transformBinReg ([Ref]$result_property) ([Ref]$line) ([Ref]$values) ($values.count) ([Ref]$comma) ([Ref]$nb_bin) $True
$result_property = $result_property + $line
} # ExpandString


# MultiString "System.String[]"
"MultiString" {
$result_property = ""
$tmpvalues = $propertyvalue
$line = $result_name + "=hex(7):"

$comma = ""
$nb_bin=0
foreach ($val in $tmpvalues) {
$values = [System.Text.Encoding]::UNICODE.GetBytes($val + "*") # * = 2a
transformBinReg ([Ref]$result_property) ([Ref]$line) ([Ref]$values) ($values.count) ([Ref]$comma) ([Ref]$nb_bin) $True
}
$result_property = $result_property + $line

# Multistring
if ($result_property.substring($result_property.length - 1, 1) -eq ":") { # test if multistring has a value
$result_property = $result_property + "00,00" # End of multistring
} else {
if ( ($result_property.length - $result_property.LastIndexOfAny("`r`n")) -gt 73) {
$result_property = $result_property + ",00,\`r`n 00" # End of multistring
} else {
$result_property = $result_property + ",00,00" # End of multistring
}
}
} # MultiString

# Binary "System.Byte[]"
"Binary" {
$result_property = ""
$values = $propertyvalue
$line = $result_name + "=hex:"
$comma = ""
$nb_bin=0
transformBinReg ([Ref] $result_property) ([Ref] $line) ([Ref] $values) $values.count ([Ref] $comma) ([Ref] $nb_bin)
$result_property = $result_property + $line
} # End Binary


# DWord "System.Int32"
"DWord" {
$val = ([String]::Format("{0:x8}", $propertyvalue))
$result_property = $result_name + "=dword:$val"
} # DWord

# QWord
"QWord" {
$val = ([String]::Format("{0:x16}", $propertyvalue))
$result_property = $result_name + "=hex(b):" + $val.Substring(14,2) + "," + $val.Substring(12,2) + "," + $val.Substring(10,2) + "," + $val.Substring(8,2) + "," + $val.Substring(6,2) + "," + $val.Substring(4,2) + "," + $val.Substring(2,2) + "," + $val.Substring(0,2)
} # QWord

# Unknown
"Unknown" {
# GetValue does not support reading values of type REG_NONE or REG_LINK
# http://msdn.microsoft.com/en-us/library/kk88y0s0.aspx
$hKey = New-Object UIntPtr
$keyname = $key.Name
$hKeyLeft = $keyname.Substring(0, $keyname.IndexOf('\'))
$hKeyRight = $keyname.Substring( ($keyname.IndexOf('\') + 1) , ($keyname.Length - $keyname.IndexOf('\') - 1) )
$result_func = [Win32Functions.Registry]::RegOpenKeyEx($hKeyLeft, $hKeyRight, 0, "KEY_READ", [ref] $hKey)

$values = ""
$nb_values = 0
if ($result_func -eq 0) {
$lpType = New-Object uint32
$lpData = New-Object System.Text.StringBuilder
$lpcbData = New-Object uint32
# Get Type & Size
$result_func = [Win32Functions.Registry]::RegQueryValueEx($hKey, $property_name, $Null, [ref] $lpType, $lpData, [ref] $lpcbData)
# ERROR_MORE_DATA = 234
if ($result_func -eq 234) {
If ($lpType -eq 0) {
$lpData = New-Object System.Text.StringBuilder ([int] $lpcbData)
$result_func = [Win32Functions.Registry]::RegQueryValueEx($hKey, $property_name, $Null, [ref] $lpType, $lpData, [ref] $lpcbData)
$values = [System.Text.Encoding]::UNICODE.GetBytes($lpData) # $values.count can be different from $lpcbData
$nb_values = $lpcbData
}

}
}
$result_func = [Win32Functions.Registry]::RegCloseKey($hKey)

$result_property = ""
$line = $result_name + "=hex(0):"
$comma = ""
$nb_bin=0
transformBinReg ([Ref]$result_property) ([Ref]$line) ([Ref]$values) ($nb_values) ([Ref]$comma) ([Ref]$nb_bin)
$result_property = $result_property + $line
} # End Unknown

# Default -> error typename not defined
Default {
$result_property=";ERROR: type $TypeNameOfValue not defined " + "path:" + $key.PsPath + " Name:" + $propertyname
Write-Host $result_property
} # end Default
}
$result = $result + $result_property + "`r`n"
}
#If ($debug) { Write-Host $result }
$result | Out-File -append $outputfile
$result=""

$SubKeyNames = $Key.GetSubKeyNames()
foreach($subkeyname in $SubKeyNames) {
ExportReg $hiveKey "$registrypath\$subkeyname" $Computername $outputfile
}


}


# ----------------------------

Function TestFilePath {
Param($filename)

If ((Test-Path("$filename")) -eq $False){
If ((Test-Path("$strCurDir\$filename")) -eq $False){
Write-Host "ERROR : file $filename NOT exist"
Write-Host "ERROR : file $strCurDir\$filename NOT exist"
Exit
} Else {
$filename = "$strCurDir\$filename"
}
}

return $filename
}

# ----------------------------

#
# MAIN PROGRAM
#

# Verify Arguments Number
If($Args.Count -lt 2) {
Write-Host "Syntax:"$MyInvocation.MyCommand.Name "registry outputfilename [computername]"
Write-Host " Example:"$MyInvocation.MyCommand.Name" 'HKCM:\Software\Microsoft\Windows\CurrentVersion\Run' 'outputfile.txt' "
Write-Host " Example:"$MyInvocation.MyCommand.Name" 'HKEY_CURRENT_USER\Control Panel\Desktop' 'outputfile.txt' computername"
Write-Host
Break
}

# Registry Path
$registrypath = $Args[0]

# Output file
$outputfile = $Args[1]

# Computername
if ($Args.Count -gt 2) {
$Computername = $Args[2]
} else {
$Computername = $env:Computername
}
If ($debug) { Write-Host $Computername }


# Register registry functions
If (-not ("Win32Functions.Registry" -as [Type])) {
$type = Add-Type -MemberDefinition $signature -Name Registry -Namespace Win32Functions -Using System.Text -PassThru
} else {
If ($debug) { Write-Host "Win32Functions.Registry already Registered" }
}

# Write output file with registry informations
$Content = "Windows Registry Editor Version 5.00" + "`r`n" # "REGEDIT4"
$Content | Out-File $outputfile
$hKeyLeft = $registrypath.Substring(0, $registrypath.IndexOf('\'))
$hKeyRight = $registrypath.Substring( ($registrypath.IndexOf('\') + 1) , ($registrypath.Length - $registrypath.IndexOf('\') - 1) )
switch ($hKeyLeft) {
"HKEY_CLASSES_ROOT" { $hiveKey = "ClassesRoot"}
"HKEY_CURRENT_USER" { $hiveKey = "CurrentUser"}
"HKEY_LOCAL_MACHINE" { $hiveKey = "LocalMachine"}
"HKEY_USERS" { $hiveKey = "Users"}
"HHKEY_CURRENT_CONFIG" { $hiveKey = "CurrentConfig"}
default {
Write-Host "ERROR: you must use one of the following key: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKCU, HKLM, HKU, HKCC"
Exit 1
}
}

ExportReg $hiveKey $hKeyRight $Computername $outputfile

# ----------------------------

Monday, November 29, 2010

How to develop your own VMWare application in C#

First, download and install "Visual Studio Express 2008" (http://www.microsoft.com/express/Downloads/)
Then download and install "VMware vSphere Web Services SDK" (http://www.vmware.com/download/sdk/)

In file Build2008.cmd (from your "VMware vSphere Web Services SDK directory\samples\DotNet" directory) if you installed your VS2008 Express in an other directory than default directory modify line
set VSINSTALLDIR="C:\Program Files\Microsoft Visual Studio 9.0"

Run a command line prompt.

Verify in command line prompt you can run
- WSDL.exe (by default at C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin)
- csc.Exe (by default at C:\WINDOWS\Microsoft.NET\Framework\v3.5)
- VCSExpress.exe (by default at C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE)

Else add path of these programs with something like this in command line before running Build2008.cmd:
Set path=%path%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE

In command line prompt do not forget to run this line too:
set WSDLFILE=your VMware vSphere Web Services SDK directory\wsdl

Then run Build2008.cmd
You should have all your .dll libraries created.

Run in your VMware vSphere Web Services SDK directory\samples\DotNet\cs\SimpleClient\bin\Debug this line to verify all is ok:
SimpleClient.exe https://yourvc/sdk yourvcuser yourvcpassword

Now, if you need to create your own application, just add line
using Vim25Api;
and in your project "add reference" tab browse
"Vim25Service2008.dll" and "Vim25Service2008.XmlSerializers.dll"

Use examples in your vSphere Web Services SDK\directory\samples\DotNet\cs for helping you to create your 1st C# vmware application