Hyper-V VM Notlarına Biraz Güç Eklemek
Evde çalıştığım için Hyper-V ortamıma büyük ölçüde güveniyorum. İşyerinde Hyper-V kullanıyorsanız aynı durumun sizin için de geçerli olduğunu varsayıyorum. Çok fazla test yaptığım için bazen belirli bir VM'de neyin çalıştığını hatırlamak zor oluyor. Bu kutuyu PowerShell v5'e güncelledim mi? Bu VM Windows Server 2016 TP 3 veya TP4 çalıştırıyor mu?
Hyper-V sanal makineleri, sistem bilgilerini depolamak için ideal yer gibi görünen, not tutabileceğiniz bir ayara sahiptir. Windows makinelerimin çoğu genel ağımda olduğundan ve sanal makine adı bilgisayar adıyla aynı olduğundan, her sanal makineye bağlanmak, bazı sistem bilgilerini almak ve ilgili notu güncellemek için PowerShell uzaktan iletişimini kolaylıkla kullanabilirim.
İhtiyacım olan sistem bilgisini almak için böyle bir komut çalıştırabilirim.
Get-WmiObject win32_Operatingsystem |
Select @{Name="OperatingSystem";Expression={$_.Caption}},
@{Name="ServicePack";Expression={$_.CSDVersion}},
@{Name="PSVersion";Expression= {$psversiontable.PSVersion}},
@{Name="Hostname";Expression={
If (Get-Command Resolve-DNSName -ErrorAction SilentlyContinue) {
(Resolve-DnsName -Name $env:computername -Type A).Name
}
else {
[system.net.dns]::Resolve($env:computername).hostname
}
}}
Bunun gibi bir sonuç alıyorum:
Kodumda, farklı olması ihtimaline karşı bilgisayar adını eklemek istiyorum. Sunucuda Resolve-DNSName cmdlet'i varsa, onu çağırırım, aksi takdirde adı çözümlemek için .NET Framework'ü kullanırım.
Notes özelliğini ayarlamak için Set-VM'yi kullanabilirim.
$VM = get-vm chi-dc02
Set-VM $VM -Notes $newNote
Bu davranışın mevcut notların yerini alacağını unutmayın. Son kodumda bunu dikkate alıyorum ve varsayılan olarak sistem bilgilerini ekliyorum. Ama dilerseniz not içeriğini değiştirebilecek bir parametre var.
Son kodum ayrıca VM'nin adı yerine IP adresini kullanacak bir parametre içeriyor. Test alanımın parçası olmayan birkaç sanal makinem var ancak adlarını DNS'ime kaydediyorum.
İşte betiğin tamamı.
#requires -version 4.0
#requires -module Hyper-V
<#
Update the Hyper-V VM Note with system information
The script will make a PowerShell remoting connection to each virtual machine using the
VM name as the computer name. If that is not the case, you can use the detected IP address
and then connect to the resolved host name. Alternate credentials are supported for
the remoting connection.
The default behavior is to append the information unless you use -Replace.
The default is all virtual machines on a given server, but you can specify an
individual VM or use a wild card.
You can only update virtual machines that are currently running.
Usage:
c:\scripts\Update-VMNote chi* -computername chi-hvr2 -credential globomantics\administrator -replace
#>
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(Position=0)]
[ValidateNotNullorEmpty()]
[Alias("name")]
[string]$VMName = "*",
[Alias("CN")]
[string]$Computername = $env:COMPUTERNAME,
[Alias("RunAs")]
[System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty,
[Switch]$ResolveIP,
[Switch]$Replace
)
Write-Verbose "Starting: $($MyInvocation.Mycommand)"
Write-Verbose "Getting running VMs from $($Computername.ToUpper())"
$VMs = (Get-VM -Name $VMName -computername $computername).Where({$_.state -eq 'running'})
if ($VMs) {
foreach ($VM in $VMs) {
Write-Host "Processing $($VM.Name)" -ForegroundColor Green
if ($ResolveIP) {
#get IP Address
$IP = (Get-VMNetworkAdapter $VM).IPAddresses | where {$_ -match "\d{1,3}\." } | select -first 1
#resolve IP address to name
$named = (Resolve-DnsName -Name $IP).NameHost
}
else {
#use VMname
$named = $VM.name
}
#get PSVersion
#get Operating System and service pack
#resolving hostname locally using .NET because not all machines
#may have proper cmdlets
$sb = {
Get-WmiObject win32_Operatingsystem |
Select @{Name="OperatingSystem";Expression={$_.Caption}},
@{Name="ServicePack";Expression={$_.CSDVersion}},
@{Name="PSVersion";Expression= {$psversiontable.PSVersion}},
@{Name="Hostname";Expression={
If (Get-Command Resolve-DNSName -ErrorAction SilentlyContinue) {
(Resolve-DnsName -Name $env:computername -Type A).Name
}
else {
[system.net.dns]::Resolve($env:computername).hostname
}
}}
} #close scriptblock
#create a hashtable of parameters to splat to Invoke-Command
$icmHash = @{
ErrorAction = "Stop"
Computername = $Named
Scriptblock = $sb
}
#add credential if specified
if ($Credential.username) {
$icmHash.Add("Credential",$Credential)
}
Try {
#run remoting command
Write-Verbose "Getting remote information"
$Info = Invoke-Command @icmHash | Select * -ExcludeProperty RunspaceID
#update Note
Write-Verbose "`n$(($info | out-string).Trim())"
if ($Replace) {
Write-Verbose "Replacing VM Note"
$newNote = ($info | out-string).Trim()
}
else {
Write-Verbose "Appending VM Note"
$current = $VM.Notes
$newNote = $Current + "`n" + ($info | out-string).Trim()
}
Set-VM $VM -Notes $newNote
#reset variable
Remove-Variable Info
} #try
Catch {
Write-Warning "[$($VM.Name)] Failed to get guest information. $($_.exception.message)"
} #catch
} #foreach VM
} #if running VMs found
else {
Write-Warning "Failed to find any matching running virtual machines on $Computername"
}
Write-Verbose "Ending: $($MyInvocation.Mycommand)"
Bunun bir komut dosyası olduğunu ve bir işlev olmadığını unutmayın. Artık sanal makinelerimi kolayca güncelleyebiliyorum.
C:\scripts\Update-VMNote.ps1 chi* -Computername chi-hvr2 -Credential globomantics\administrator -replace
Ve işte sonuç:
Elbette, notta istediğiniz herhangi bir bilgiyi içerecek şekilde komut dosyasını değiştirebilirsiniz.
Bunu yararlı bulursanız umarım bana haber verirsiniz.
Eğlence!
GÜNCELLEME 11 OCAK 2016
Betiği güncelledim ve bir fonksiyona dönüştürdüm. Artık sanal makineleri fonksiyona aktarabilirsiniz. Not bilgilerini görebilmeniz için bir Geçiş parametresi de ekledim. İşlev, https://Gist.github.com/jdhitsolutions/6f17c1d901ff870ff7a3 adresindeki GitHub'da barındırılmaktadır.