Category Archives: PowerShell

Automate the installation of Hyper-V VMintegration services with PowerShell

Tired of installing VM integration services manually in your Hyper-V environment? Here´s a script to help you with that!

Tip, this hotfix requires reinstallation of all your VMs integration services: Https://support.microsoft.com/en-us/kb/3063283

This script only works on x64 machines!

vmint

Begin Script
========================================================================================================

<#
Powershell Script for updating of Hyper-V Integration Services
2015-11-23 Harri Förberg, Förbergs IT AB
http://itharri.com
http://www.forbergsit.se
Warning, this script could potentially reboot a lot of VM:s in rapid succession. Use wisely, and with caution.
Prequisites: Mount and copy the contents of C:\Windows\System32\vmguest.iso (found on your Hyper-V host), copy the content to a shared folder on the server that will used to execute the script
C:\Temp\IntegrationSvc is used in the script below
— You might need to have you GPO:s adjusted to allow file copy from the server where you execute this script. —
#>

# Fill the latest Integration Services number here
$ICSVer = ”6.3.9600.17831” # This was the latest version 2015-11-23 (Delivered in a Hotfix – https://support.microsoft.com/en-us/kb/3063283)

#Specify your list of all Hyper-V Hosts
$HPVServer = ”HPV01” , ”HPV02” # <– Change to your servers

# Check all Running VM:s on all HPV hosts for ICS versions lower than our preset in line >> 13
$VMNames = Get-VM -ComputerName $HPVServer | ? {$_.IntegrationServicesVersion -lt $ICSVer -and $_.State -eq ”Running”} # This would be a good place to narrow your search parameters

# Check if any VM:s are in need of updating
if
($VMNames -eq $null) {Write-Host ”No VM:s detected with old versions” -ForegroundColor Red}
else
{
Write-Host ”Found VM:s with old Integration Services, starting upgrade process” -ForegroundColor Green

# Install Integration Services on VMs
foreach ($VirtualMachine in $VMNames)
{
$VMName = $VirtualMachine.VMName

# If copy fails here, check firewall rules on your client server.
write-host ”Copying installation files to $VMName
Copy-Item -Path C:\Scripts\IntegrationSvc -Destination ”\\$VMName\C$\temp\IntegrationSvc” -Recurse -Force
write-host ”Installing integration services…”
$scriptblock = {cmd.exe /C ”C:\Temp\IntegrationSvc\support\amd64\setup.exe /quiet /norestart”} # <– ADD or Remove /norestart if you want or dont want to reboot all VM:s after the installation completes!
Invoke-Command -scriptblock $scriptblock -computername $VMName
# Cleanup of copied installation files
write-host ”Cleanup…”
Remove-Item -Path ”\\$VMName\C$\temp\IntegrationSvc” -Recurse -Force
# Display Status
Write-Host $VMName updated” -ForegroundColor Green
}
}
Write-Host ”All done” -ForegroundColor DarkMagenta

========================================================================================================

End Script

Annonser

Hur vi installerar en massa hotfixar utan WSUS via PowerShell

Markus Lassfolk har en bra blogpost som beskriver alla hotfixar som du borde ha i din Datacenterlösning. Han beskriver förvisso hur du kan få in dom i WSUS, men det är lite knepigt då vissa patchar helt enkelt inte finns i Windows Update Catalogue. (Ladda ner lämpliga hotfixar, och packa upp dom till en mapp)

Här har du en alternativ lösning som installerar hotfixarna från en central plats med hjälp av PowerShell. Den loggar vilka servrar du har installerat, samt visar feedback på hur installationen gick.

Lägger du till fler hotfixar i framtiden så kommer dom automatiskt att installeras om du kör om skriptet, utan att du behöver modifiera i skriptet dessutom. Packa bara upp MSU filerna till den delade katalogen.

script

Ett speciellt tack till Jimmy Veerman & Rickard Lundqvist på Förbergs IT som hjälpte till med Scriptet.

Tips för flera vanliga VMM & Scom frågor

  1. När du patchar din VMM server, se till att samtidigt patcha din SCOM server till samma version (allra helst när vi pratar update rollups)
  2. När du patchat din VMM server, se då till att inte glömma uppdatera VMM agenterna, mycket vanligt att detta glöms bort.
  3. Uppdatera även SCOM management packet, den läggs under \Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\ManagementPacks på den disken där du installerade VMM. Använd SCOM konsolen på din VMM server för att importera dessa.
  4. Se till att alla dina VMM infrastrukturobjekt övervakas av SCOM
  5. Bugg: Har du en ”Stored Virtual Machine” i Libraryt, så kan detta ibland förhindra din SCOM Connection från att lyckas koppla upp sig igen i samband med en uppgradering. Workaround: Ta bort och lägg tillbaka den sparade VM:en.
  6. LÄS ALLTID KB Artikeln för VMM & SCOM när update Rollup släpps, det står en massa bra information där!

Väl mött itHarri

weblogo_182x45

Automagisk dokumentation av Exchange 2013 med PowerShell

Det kan f*n inte finnas nåt tråkigare än att dokumentera inställningar för hand, däremot är det riktigt kul att skriva PowerShell skript 🙂

Utöver att du slipper dokumentera för hand, så får du kvalitet på dokumentationen, samt att du givetvis schemalägger skriptet så att du varje månad skapar en ny, tänk vad skönt att kunna följa historik på förändringar!

Skriptet är skrivet för mindre miljöer med en Exchange Site, så den dokumenterar ALLA servrar som finns, har du många siter så kan du ändra get satserna så att de bara hämtar servrarna från din lokala site.

### Exchange 2013 dokumentation script
# 2014-06-03 Harri Förberg http://itharri.com
#
### Start document and set time and date

$Time = (Get-Date -Format yyyy-MM-dd)
Write-Output ”Created Date $Time” | Out-File C:\Script\ExDoc_$Time.txt
Write-Output ” ” | Out-File C:\Script\ExDoc_$Time.txt -Append

# Get Server list
Write-Output ”*** Servers ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-ExchangeServer | FT -AutoSize NAME, ServerRole, Edition, AdminDisplayVersion) | Out-File C:\Script\ExDoc_$Time.txt -Append

# Database information
Write-Output ”*** Databases ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
$dbs = Get-MailboxDatabase -Status
foreach ($db in $dbs)
{
Write-Output (($db.Name) + (” Size ” ) + ($db.DatabaseSize ) + (” Free Space in DB ”) + ($db.AvailableNewMailboxSpace)) | Out-File C:\Script\ExDoc_$Time.txt -Append
}
Write-Output (Get-MailboxDatabase | FT Name, ServerName, EdbFilePath, LogFolderPath, IssueWarningQuota, ProhibitSendQuota, ProhibitSendReceiveQuota, DeletedItemRetention, MailboxRetention, IndexEnabled, CircularLoggingEnabled, WhenChanged -AutoSize) | Out-File C:\Script\ExDoc_$Time.txt -Append

# Count mailboxes per DB
Write-Output ”*** Mailbox statistics ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
$collection = (Get-MailboxDatabase).Name
foreach ($item in $collection)
{
$Count = (get-mailbox -Database $item -ResultSize Unlimited).count
Write-Output ”mailboxes in $item = $Count ” | Out-File C:\Script\ExDoc_$Time.txt -Append
}
Write-Output ((”Totalt nr of mailboxes = ”) + ((get-mailbox -ResultSize Unlimited).count)) | Out-File C:\Script\ExDoc_$Time.txt -Append

# Mobile Devices
Write-Output ”*** ActiveSync Device AccessRules ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-ActiveSyncDeviceAccessRule | FT Name, Identity, QueryString, Characteristic, AccessLevel, IsValid, WhenChanged -AutoSize) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”*** ActiveSync User Statistics ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ((Get-CASMailbox -OrganizationalUnit ”OU=Accounts,OU=Data,DC=sbgstad,DC=se” –ResultSize Unlimited -Filter {HasActiveSyncDevicePartnership -eq $True}).PrimarySmtpAddress | ForEach {Get-MobileDeviceStatistics -Mailbox $_} | Group DeviceModel | Sort Count -Descending | FT Count, Name -AutoSize) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”See http://www.enterpriseios.com/wiki/Complete_List_of_iOS_User_Agent_Strings for User Agent Details on IOS Devices” | Out-File C:\Script\ExDoc_$Time.txt -Append

# Public Folders
Write-Output ”*** Public Folders ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-Mailbox -PublicFolder | FT Name, ServerName, RetainDeletedItemsFor, IssueWarningQuota, ProhibitSendQuota, ProhibitSendReceiveQuota -AutoSize) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”*** Public Folder Statistik ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
$PFStat = ((Get-PublicFolder \ -Recurse).Count)
Write-Output ”$PFStat Publicfolders in Org” | Out-File C:\Script\ExDoc_$Time.txt -Append

# Get DAG
Write-Output ”*** DAG ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-DatabaseAvailabilityGroup | fl Name, Servers, WitnessServer, WitnessDirectory, DatabaseAvailabilityGroupIpAddresses) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-MailboxServer | ft Name, DatabaseAvailabilityGroup, AutoDatabaseMountDial, DatabaseCopyAutoActivationPolicy) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-MailboxDatabaseCopyStatus) | Out-File C:\Script\ExDoc_$Time.txt -Append

# Exchange Connectors
Write-Output ” ” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”*** Send Connectors ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-SendConnector | FT Name, Comment, AddressSpaces, MaxMessageSize, Port, SmartHostsString, SourceTransportServers, ProtocolLoggingLevel -AutoSize) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ” ” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”*** Receive Connectors ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-ReceiveConnector | FT Name, TransportRole, Fqdn, MaxRecipientsPerMessage, MaxMessageSize, Banner, PermissionGroups, ProtocolLoggingLevel -AutoSize) | Out-File C:\Script\ExDoc_$Time.txt -Append

# Offline Addressbook
Write-Output ”*** Offline Addressbooks ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-OfflineAddressBook | FT Name, Versions, AddressLists, WebDistributionEnabled, LastTouchedTime, VirtualDirectories -AutoSize) | Out-File C:\Script\ExDoc_$Time.txt -Append

# Get IIS Directories
Write-Output ”***OWA Virtual Directories ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-OwaVirtualDirectory | FL Identity, OwaVersion, InternalAuthenticationMethods, ExternalAuthenticationMethods, BasicAuthentication, WindowsAuthentication, DigestAuthentication, FormsAuthentication, OAuthAuthentication, AdfsAuthentication, DefaultDomain, InternalUrl, ExternalUrl, WhenChanged) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”***ECP Virtual Directories ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-EcpVirtualDirectory | FL Identity, InternalAuthenticationMethods, ExternalAuthenticationMethods, BasicAuthentication, WindowsAuthentication, DigestAuthentication, FormsAuthentication, OAuthAuthentication, AdfsAuthentication, DefaultDomain, InternalUrl, ExternalUrl, WhenChanged) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”***EWS Virtual Directories ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-WebServicesVirtualDirectory | FL Identity, InternalAuthenticationMethods, ExternalAuthenticationMethods, BasicAuthentication, WindowsAuthentication, DigestAuthentication, OAuthAuthentication, AdfsAuthentication, InternalUrl, ExternalUrl, WhenChanged) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”***EAS Virtual Directories ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-ActiveSyncVirtualDirectory | FL Identity, InternalAuthenticationMethods, ExternalAuthenticationMethods, BasicAuthEnabled, WindowsAuthEnabled, CompressionEnabled, ClientCertAuth, InternalUrl, ExternalUrl, WhenChanged) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”***OAB Virtual Directories ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-OabVirtualDirectory | FL Identity, InternalAuthenticationMethods, ExternalAuthenticationMethods, BasicAuthentication, WindowsAuthentication, InternalUrl, ExternalUrl, WhenChanged) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”*** Autodiscover Directories ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-AutodiscoverVirtualDirectory | FL Identity, InternalAuthenticationMethods, ExternalAuthenticationMethods, BasicAuthentication, WindowsAuthentication, DigestAuthentication, OAuthAuthentication, AdfsAuthentication, WhenChanged) | Out-File C:\Script\ExDoc_$Time.txt -Append

# Get Client Access Server & Outlook Anywhere Config
Write-Output ”*** ClientAccessServer Config ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-ClientAccessServer | fl Name, OutlookAnywhereEnabled, AutoDiscoverServiceInternalUri, WhenChanged) | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”*** Outlook Anywhere Config ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-OutlookAnywhere | fl Server, Identity, ExternalHostname, InternalHostname, SSLOffloading, IISAuthenticationMethods, ExternalClientsRequireSsl, InternalClientsRequireSsl, WhenChanged) | Out-File C:\Script\ExDoc_$Time.txt -Append

# Get Exchange Certificates
Write-Output ” ” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ”*** Exchange Certificates ***” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output ” ” | Out-File C:\Script\ExDoc_$Time.txt -Append
$cert = (Get-ExchangeServer).Name
foreach ($item in $cert)
{
Write-Output ”$item” | Out-File C:\Script\ExDoc_$Time.txt -Append
Write-Output (Get-ExchangeCertificate -Server $item) | FT Subject, Issuer, NotBefore, NotAfter | Out-File C:\Script\ExDoc_$Time.txt -Append
}

Virtual Machine Converter 2 är ute

Klarar nu av att genomföra det som man förväntar sig, till exempel avinstallera VMware tools, och flytta över ip adresserna till rätt NIC:s i Hyper-V.  Den finns i två versioner, enklare MVMC samt MAT+MVMC som är tänkt för lite större migreringar.

VM prestanda i Hyper-V

Jag felsöker alltid då och då prestanda flaskhalsar i Hyper-V och tänkte dela med mig av ett skript som enkelt låter en kontrollera hur prestandan ser ut i er egen miljö.

Som exempel ska jag beskriva ett fel som jag hade i min egen labmiljö:

Min labbrigg består av server med Intels X79 Chipset. Jag hade fenomenal prestanda i Windows Server 2012 R2 Storage Spaces på disken, hastigheter på över 1GB/sec… tills jag startade ett par VM:s. Då gick disken upp i 100% Active Time, och hastigheterna kröp ner till kb/sec hastighet. Så fort jag stannat alla VM:s gick Active Time ner till 0%. Det roliga var att samma inträffade när jag körde VM:s över SMB mot en annan maskin också. Lösningen på det hela var att uppgradera Bios och installera Intels Chipset Driver till senaste versionen.

Innan uppgradering av Bios & Drivrutiner hade jag ”AggregatedAverageLatency” på mellan 100.000-2.000.000 på vissa VM:s.

Mätningarna skrev över en 20 sekunders intervall, och över Normalized IOPS av 8k storlek. Nedan ett exempel när allting ser normalt ut.

measure-vm

# Kör detta direkt på din Hyper-V host som du vill mäta aktiviteten på

# Slå på & av mätarna
get-vm * | Enable-VMResourceMetering
get-vm * | Disable-VMResourceMetering

# Se vilka som är aktiverade
get-vm * | Format-List Name,ResourceMeteringEnabled

# Se CPU & minnes & nätverksnyttjande
get-vm | Measure-VM | FT

# Se Disk prestanda & IOPS
get-vm | Measure-VM | FT VMName, Aggr* -AutoSize

Powershell Pingverktyg

Jag brukar använda ett skript som är enkelt anpassningsbart för att snabbt pinga många maskiner, användbart när man vill testa att alla maskinerna svarar på Ping efter en live migration från en host till en annan.

Du har två lägen som du kan köra:

Ett: Pinga alla maskiner som är startade (hittar automatiskt alla VM:s som du har)

Två: Pinga alla maskiner utifrån en textfil (Givetvis finns en oneliner för att automatiskt fylla listan åt dig!)

Jag brukar skapa en CMD fil i skriptkatalogen som startar PowerShell Skriptet, sedan brukar jag skapa en länk till skrivbordet, sätta lämpligt namn & en snygg ikon på den. Då har du den alltid lätt tillgänglig.

Skript 1, Pinga alla VM:s som är startade

#### Ping all computers
#
# Load Virtual Machine Manager Commandlets
ipmo
virtualmachinemanager

# Ping all Running VM:s
Write-Host
”Pinging all Running VM:s”
$VM
= ((Get-SCVirtualMachine | ? Status -EQ ”Running”).Name)

foreach ($name in $VM)
{
if ( Test-Connection -ComputerName $name -Count 1 -ErrorAction SilentlyContinue ) {
Write-Host $name is up” -ForegroundColor Green
}
else {
Write-Host $name is down” -ForegroundColor Red
}
}

Skript 2, Pinga efter en textfil:

#### Ping all computers in textfile
#
# First get a list of all your computers to the textfile (remove # first, the edit the list to your liking)
# (Get-SCVirtualMachine | where {$_.VirtualizationPlatform -eq ”HyperV”}).ComputerName > C:\script\computers.txt

### or this if you only have one Hyper-V host (w/o SCVMM)
# (get-vm).Name > C:\script\computers.txt

### Then ping all computers in this list

$names = Get-Content ”C:\script\computers.txt”

foreach ($name in $names) {
if ( Test-Connection -ComputerName $name -Count 1 -ErrorAction SilentlyContinue ) {
Write-Host $name is up” -ForegroundColor Green
}
else {
Write-Host $name is down” -ForegroundColor Red
}
}

Pactha dina WIM & VHD(x) offline

John Savill har publicerat en Youtube video som beskriver hur du kan offlinepatcha dina VHX(x) och WIM filer. Kanonbra om du har en syspreppad image som du inte vill starta upp!

Här kan du se instruktionsvideon
http://www.youtube.com/watchv=cOUlW2bJnK0&feature=share&list=UUpIn7ox7j7bH_OFj7tYouOQ

Här kan du hämta koden
http://www.savilltech.com/downloads/Install-Patch/Install-Patch.psm1

Kortfattad instruktion:
Kopiera Install-Patch.psm1
till $env:USERPROFILE\Documents\WindowsPowerShell\Modules\Install-Patch
Importera följande moduler i powershell:
import-module install-patch
import-module Hyper-V

Kör sedan kommandot:
Install-Patch D:\VHD\WIN2012GM.vhdx D:\Updates

//Harri

Behöver du köra Windows 2000/NT4 på Hyper-V 2012?

Men det är ju inte supporterat kommer det ett standardsvar på posten. Men, verkligheten är att har man bara en enda maskin som inte går att uppgradera så vill man nog gärna flytta den också. Microsoft passade på att ta bort bakåtkompabiliteten från Hyper-V GUI:t men i PowerShell finns den kvar.

Visst du får ingen support från Microsoft för lösningen, men good luck att få support från MS på Windows 2000/NT4 på nån annan plattform heller 🙂

Så för att aktivera kompabilitetsläge för äldre operativ som Windows 2000 och NT4

Get-VMProcessor dinvm | Set-VMProcessor -CompatibilityForOlderOperatingSystemsEnabled $true

Ladda PowerShell ISE kommandon automatiskt

Jag föredrar PowerShell ISE över ”Old fashion” PS konsolen vilken dag som helst. Dock laddar den inte Exchange, VMM m.m. modulerna automatiskt åt mig.

För att råda bot på detta så kan vi skapa en profil för ISE. Du gör detta genom att skapa en profile.ps1 fil som du sparar i dina dokument under WindowspowerShell mappen.

När profilen är skapad kommer ISE (och vanliga PS) alltid att utföra det du önskar av den vid uppstart, lite som autoexec.bat i dos en gång i tiden 🙂


Sedan ändrar du filen beroende på vad du vill att den skall starta:

Exempel 1: Exchange 2013

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://cas.domain/PowerShell/ -Authentication Kerberos

Import-PSSession $Session

Exempel 2: Exchange 2010 

add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010

Exempel 3: SCVMM 2012

Get-Module -ListAvailable *virtual* | import-module

Skulle du hellre vilja starta modulen från ISE menyn?

$psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add(
”Connect to Exchange”,
    {
$s = New-PSSession -ConfigurationName Microsoft.Exchange `
       -ConnectionUri http://cas.domain.com/PowerShell/ `
-Authentication Kerberos

       Import-PSSession $s
    },
 ”Control+Alt+Z”
)

Detta ger dig följande resultat:


Vill du använda profilerna för alla användare? Inga problem, detta var bara en av de sex profilerna som du kan ställa in i PowerShell. Läs vidare på: Hey, Scripting Guy! Blog