search
Categories
Sponsors
VirtualMetric Hyper-V Monitoring, Hyper-V Reporting
Archive
Blogroll

Badges
MCSE
Community

Cozumpark Bilisim Portali
Posted in Virtual Machine Manager, Windows Powershell | 3 Comments | 7,783 views | 16/03/2014 08:12

Due to WMI changes on Hyper-V Server 2012 R2, you need to use following script to get Virtual Machine info.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
function Get-VMGuestInfo
{
<#
    .SYNOPSIS
 
        Gets virtual machine guest information
 
    .EXAMPLE
 
        Get-VMGuestInfo -VMName Test01
 
    .EXAMPLE
 
        Get-VMGuestInfo -VMName Test01 -HyperVHost Host01
 
    .NOTES
 
        Author: Yusuf Ozturk
        Website: http://www.yusufozturk.info
        Email: ysfozy[at]gmail.com
 
#>
 
[CmdletBinding(SupportsShouldProcess = $true)]
param (
 
    [Parameter(
        Mandatory = $true,
        HelpMessage = 'Virtual Machine Name')]
    $VMName,
 
    [Parameter(
        Mandatory = $false,
        HelpMessage = 'Hyper-V Host Name')]
    $HyperVHost = "localhost",
 
	[Parameter(
        Mandatory = $false,
        HelpMessage = 'Debug Mode')]
    [switch]$DebugMode = $false
)
	# Enable Debug Mode
	if ($DebugMode)
	{
		$DebugPreference = "Continue"
	}
	else
	{
		$ErrorActionPreference = "silentlycontinue"
	}
 
	$VMState = (Get-VM -ComputerName $HyperVHost -Name $VMName).State
 
	if ($VMState -eq "Running")
	{
		filter Import-CimXml
		{
			$CimXml = [Xml]$_
			$CimObj = New-Object -TypeName System.Object
			foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY"))
			{
				if ($CimProperty.Name -eq "Name" -or $CimProperty.Name -eq "Data")
				{
					$CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE
				}
			}
			$CimObj
		}
 
		$VMConf = Get-WmiObject -ComputerName $HyperVHost -Namespace "root\virtualization\v2" -Query "SELECT * FROM Msvm_ComputerSystem WHERE ElementName like '$VMName' AND caption like 'Virtual%' "
		$KVPData = Get-WmiObject -ComputerName $HyperVHost -Namespace "root\virtualization\v2" -Query "Associators of {$VMConf} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent"
		$KVPExport = $KVPData.GuestIntrinsicExchangeItems
 
		if ($KVPExport)
		{
			# Get KVP Data
			$KVPExport = $KVPExport | Import-CimXml
 
			# Get Guest Information
			$VMOSName = ($KVPExport | where {$_.Name -eq "OSName"}).Data
			$VMOSVersion = ($KVPExport | where {$_.Name -eq "OSVersion"}).Data
			$VMHostname = ($KVPExport | where {$_.Name -eq "FullyQualifiedDomainName"}).Data
		}
		else
		{
			$VMOSName = "Unknown"
			$VMOSVersion = "Unknown"
			$VMHostname = "Unknown"
		}
	}
	else
	{
		$VMOSName = "Unknown"
		$VMOSVersion = "Unknown"
		$VMHostname = "Unknown"
	}
 
	$Properties = New-Object Psobject
	$Properties | Add-Member Noteproperty VMName $VMName
	$Properties | Add-Member Noteproperty VMHost $HyperVHost
	$Properties | Add-Member Noteproperty VMState $VMState
	$Properties | Add-Member Noteproperty VMOSName $VMOSName
	$Properties | Add-Member Noteproperty VMOSVersion $VMOSVersion
	$Properties | Add-Member Noteproperty VMHostname $VMHostname
	Write-Output $Properties
}

Usage of this script:

Get-VMGuestInfo -VMName TEST01 -HyperVHost VMHOSTT01

That will output like:

VMName      : TEST01
VMHost      : VMHOSTT01
VMState     : Running
VMOSName    : Windows Server 2008 R2 Enterprise
VMOSVersion : 6.1.7601
VMHostname  : TEST01.domain.contoso.com

This script also works on Hyper-V Server 2012 without R2.


Posted in Windows Powershell, Windows Server | 2 Comments | 2,438 views | 14/03/2014 10:09

You can check all reverse DNS records with DNS records with following script to see if they are equal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$Servers = Get-DnsServerResourceRecord -ZoneName contoso.domain.com
 
foreach ($Server in $Servers)
{
	# Clear Values
	$ServerName = $Null;
	$DNSName = $Null;
	$DNSHostName = $Null;
	$DNSIPAddress = $Null;
	$ReverseDNSHostName = $Null;
 
	# Resolve DNS Name
	$ServerName = $Server.HostName
	$DNSName = (Resolve-DnsName $ServerName)
 
	if ($DNSName)
	{	
		# Get Reverse DNS Name
		$DNSHostName = $DNSName.Name
		$DNSIPAddress = $DNSName.IPAddress
		$ReverseDNSHostName = ([System.Net.Dns]::GetHostByAddress("$DNSIPAddress")).HostName
 
		if ($DNSHostName -eq $ReverseDNSHostName -and $ReverseDNSHostName -ne $Null)
		{
			Write-Host "."
		}
		else
		{
			$Output = $DNSHostName + ";" + $ReverseDNSHostName
			Write-Host $Output
		}
	}
	else
	{
		Write-Host "Cannot resolve $ServerName"
	}
}

If they are not equal, that will output results.
You should run this script on a Windows Server 2012/R2 DNS server with elevated privileges.


Posted in Windows Powershell, Windows Server | 1 Comment | 5,878 views | 13/03/2014 11:57

You can use following function to get EMC Disk Numbers via PowerPath:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function Get-EMCDiskNumber
{
	param ($DiskID)
 
	function Get-PowerMtOutput
	{	
		# Get Powermt Output
		$Outputs = powermt display dev=all
 
		# Create Hash Table
		$Properties = New-Object Psobject
 
		foreach ($Output in $Outputs)
		{
			# Clear Variables
			$DiskNumber = $Null;
			$DiskID = $Null;
 
			if ($Output -ne "")
			{
				if ($Output -match 'Pseudo name=harddisk(?<Name>\d+)') { $DiskNumber = $Matches["Name"] }
				if ($Output -match 'Logical device ID=(?<ID>\w+)') { $DiskID = $Matches["ID"] }
 
				if ($DiskID) { $Properties | Add-Member Noteproperty DiskID $DiskID }
				if ($DiskNumber) { $Properties | Add-Member Noteproperty DiskNumber $DiskNumber }
			}
			else
			{
				# Output Data
				Write-Output $Properties
 
				# Create New Hash Table
				$Properties = New-Object Psobject
			}
		}
	}
 
	if ($DiskID)
	{
		Get-PowerMtOutput | Where { $_.DiskID -eq $DiskID }
	}
	else
	{
		Get-PowerMtOutput
	}
}

If you know Disk ID, you can use it:

Usage:

Get-EMCDiskNumber -DiskID "11E40"

Also you can display all disk names and ids:

Usage:

Get-EMCDiskNumber

That will output disk informations.


Posted in Windows Powershell, Windows Server | No Comment | 7,737 views | 02/03/2014 23:34

You have a Hyper-V Cluster and you use vHBA on your virtual machines?
Then you may be familiar with this error after restart your virtual machine:

TestVM: Virtual port (C003FF4CC9C5003D) creation failed with a NPIV error (Virtual machine ID 12BE2D01-D693-4488-AA5F-3715CBDA4F10)

Technet gives 2 reasons for that error as a possible cause:

Virtual Port creation failure because the WWPN is still in use because of:
· HBA failing to remove virtual port
· Host unresponsiveness

You can check documentation from here:

Only solution in that case is restarting your Hyper-V server or changing WWNN and WWPN addresses of virtual machine.
But i don’t like both ways because it takes more operator time and requires more service downtime..

So I went a little bit deeper to see what may be the reason. Because I was not able to start my virtual machine.
I installed QLogic SanSurfer on my Hyper-V host to check Physical HBA and Virtual Ports.

Then I noticed something:

Step1

My Virtual Machine was off, but its virtual port was still active on server.
After discovering that, removed that virtual port via QLogic Tools.

Step2

It worked like a charm! I was able to start my virtual machine again.
So I wrote a PowerShell script to find other inactive vHBA ports and remove them.

First, download Hyper-V vHBA PowerShell Module and put it into PowerShell Modules Directory.

You can query your inactive vHBA ports with following command:

Get-InactiveFCVirtualPort

If you want to query a remote Hyper-V server, use following command:

Get-InactiveFCVirtualPort -ComputerName RemoteServerName

That will give you inactive ports as an output:

ComputerName : VMHOST36
vHBAWWNN     : C0:03:FF:00:00:FF:FF:00
vHBAWWPN     : C0:03:FF:F1:25:95:00:0B
pHBAWWNN     : 50:06:0B:00:00:C2:62:A1
pHBAWWPN     : 50:06:0B:00:00:C2:62:A0
 
ComputerName : VMHOST36
vHBAWWNN     : C0:03:FF:00:00:FF:FF:00
vHBAWWPN     : C0:03:FF:F1:25:95:00:09
pHBAWWNN     : 50:06:0B:00:00:C2:62:A3
pHBAWWPN     : 50:06:0B:00:00:C2:62:A2

You can use following command to remove all inactive virtual ports:

Remove-InactiveFCVirtualPort

Of course you can also remove inactive virtual ports on remote server:

Remove-InactiveFCVirtualPort -ComputerName RemoteServerName

After that you should be able to start your virtual machine.

RemovePortsSS

You can also list your all virtual ports and their virtual machine information:

PS C:\Users\yusufozt> Get-FCVirtualPort
 
ComputerName : localhost
VMName       : VMDB01
VMState      : Running
VMSanName    : Switch_A
VMSanSet     : Set A
vHBAWWNN     : C0:03:FF:00:00:FF:FF:00
vHBAWWPN     : C0:03:FF:F1:25:95:00:04
pHBAWWNN     : 50:06:0B:00:00:C2:62:1F
pHBAWWPN     : 50:06:0B:00:00:C2:62:1E
 
ComputerName : localhost
VMName       : VMDB01
VMState      : Running
VMSanName    : Switch_B
VMSanSet     : Set A
vHBAWWNN     : C0:03:FF:00:00:FF:FF:00
vHBAWWPN     : C0:03:FF:F1:25:95:00:06
pHBAWWNN     : 50:06:0B:00:00:C2:62:1D
pHBAWWPN     : 50:06:0B:00:00:C2:62:1C

If you have a Hyper-V cluster, then you can use something like that:

1
2
3
4
5
6
$ClusterNodes = Get-Cluster | Get-ClusterNode
 
foreach ($ClusterNode in $ClusterNodes)
{
     Remove-InactiveFCVirtualPort -ComputerName $ClusterNode
}

That will remove all inactive virtual ports on cluster.

You should run this script on one of your Hyper-V host.