Month: June 2013

Lync Platform – Maintenance Guide

There is a set of tools available to support the daily operations of the Lync 2010 platform. The following guide aims to define the most important elements with regards to operating an Exchange 2010 farm with as few and as short operational disturbances as possible.

This guide describes the GUI-based Lync Management Console, its tools and options as well as Microsoft’s command-line shell named PowerShell. All this with references to daily operational challenges that can occur on the Lync 2010 Farm.

Furthermore this guide will contain references to the most basic parts of the maintenance support, typically deployed in relation to Lync 2010. This guide will not cover backup and restore, as this will be covered separately.

Lync 2010 Maintenance – English (Location on Google Drive)

Lync 2010 Vedligeholdelse – Dansk (Placeret på Google Drev)

Exchange Platform – Maintenance Guide

There is a set of tools available to support the daily operations of the Exchange 2010 platform. The following guide aims to define the most important elements with regards to operating an Exchange 2010 farm with as few and as short operational disturbances as possible.

This guide describes the GUI-based Exchange Management Console, its tools and options as well as Microsoft’s command-line shell named PowerShell. All this with references to daily operational challenges that can occur on the Exchange 2010 Farm.

Furthermore this guide will contain references to the most basic parts of the maintenance support, typically deployed in relation to Exchange 2010. This guide will not cover backup and restore, as this will be covered separately.

Exchange 2010 – Maintenance – English (Location on Google Drive)

Exchange 2010 – Vedligeholdelse – Dansk (Placeret på Google Drev)

Powershell – Check for Enterprise Edition, Change if not present.

Not that easy to change the licensekey of your SharePoint farm programmatically. So got help from a few of colleagues and created the below to do just that.

#--Checking for Enterprise edition key and changing if not Enterprise Edition
$ServerVersion= Get-ItemProperty "HKLM:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\WSS\InstalledProducts"
$CurrentKey= $Serverversion."{90140000-110D-0000-1000-0000000FF1CE}"

If ($CurrentKey -eq "D5595F62-449B-4061-B0B2-0CBAD410BB51")
{
write-host "Enterprise edition"
}
Else {write-host "Installing enterprise edition"
#The product key to enter
$Pkey = "<SharePoint 2010 Enterprise Edition license key"

#Get the central admin URL
$CAUrl = (Get-spwebapplication -includecentraladministration | where {$_.IsAdministrationWebApplication}).Url
$UpgradePage = $CAUrl + "_admin/SkuUpgrade.aspx"

$ie = New-Object -ComObject "InternetExplorer.Application"
$ie.Navigate($UpgradePage)

#wait for central Admin to load

while ($ie.ReadyState -ne 4)
{
sleep -Milliseconds 100
}
$RadioButton = $ie.Document.getElementById("ctl00_PlaceHolderMain_ctl00_AdminSkuUpgradeSelectFeaturesRadioGroup_RadioBtnPremiumFeatures")
$RadioButton.click()
$ProductKeyBox = $ie.Document.getElementById("ctl00_PlaceHolderMain_FormSectionPidKey_AdminSkuUpgradePidKeyTextBox_TextBoxPidKey")
$ProductKeyBox.value = $Pkey
$Button = $ie.Document.getElementById("ctl00_PlaceHolderMain_BtnSectionBottom_RptControls_BtnSaveBottom")
$Button.click()
}

Stop-Process -Name iexplore

Windows Update from Specific date.

We had a pretty standard situation, wanted to patch a bunch of servers with all patches up to a specific date. Colleague and friend of mine created the below script which proved extremely helpful.

All credits to the below mentioned people.

#------------------------------------------------------------------------
NAME: update-installer.ps1
AUTHOR: Mads H. Larsen
DATE:28/05/2013
Tested on PSversions: 2.0, 3.0

COMMENTS:
This script checks windows update for applicable updates to the system,
and then downloads and installs them. If you enter a date that is earlier
than todays date, only updates from that date or earlier are installed.

Most of the inner workings of the script is copied from:
http://www.ehow.com/how_8724332_use-powershell-run-windows-updates.html

I just added some code to compare the dates, check connectivity, show size
and elapsed time and do some formatting.
#------------------------------------------------------------------------
$runTime = [System.Diagnostics.Stopwatch]::StartNew()
cls
Write-Host "Verifying connectivity, please wait..."
[string] $url = 'https://www.update.microsoft.com'
[net.httpWebRequest] $req = [net.webRequest]::create($url)
$req.Method = "HEAD"

Try {[net.httpWebResponse] $res = $req.getResponse()}
Catch {Write-Host "$url is not available. Could not resolve $($url) " -foregroundColor red;return}
if (!($res.StatusCode -ge "200" -and $res.StatusCode -lt "400")) {Write-Host "$($url) is not available. HTTP StatusCode $($res.StatusCode)" -foregroundColor red;return}

cls

function Get-WIAStatusValue($value)
{
switch -exact ($value)
{
0 {"NotStarted"}
1 {"InProgress"}
2 {"Succeeded"}
3 {"SucceededWithErrors"}
4 {"Failed"}
5 {"Aborted"}
}
}
$sw = New-Object System.Diagnostics.Stopwatch

$number = 0
$totalSize = 0
$totalDownloaded = 0
$needsReboot = $false

$date = Get-Date (Read-Host "Input target date ($((Get-culture).DateTimeFormat.ShortDatePattern))")

$updateSession = New-Object -ComObject Microsoft.Update.Session
$updateSearcher = $updateSession.CreateUpdateSearcher()

Write-Host " - Searching for updates"
$searchResult = $updateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0")
$updates = $searchResult.Updates | Where-Object {($_.LastDeploymentChangeTime -le $date)}

Write-Host " - Found [$($updates.count)] updates to download and install"
if($($updates.count) -eq $null) {return}

$updates | Format-Table @{Expression={($_.LastDeploymentChangeTime).ToString(" dd-MM-yyyy ")};Alignment=”center”;Label="dd-MM-yyyy"},@{Expression={$_.KBArticleIDs};Alignment=”center”;Label=" KBID "},@{Expression={$_.MsrcSeverity};Alignment=”center”;Label="Severity "} -AutoSize
$totalSize = ($searchResult.Updates | measure-Object -sum MaxDownloadSize).Sum
Write-Host " ---------------------------------"
Write-Host (" = Total of {0:n2} MB to download`n" -f ($totalSize/1MB))

foreach($update in $updates)
{
# Add update to collection
Write-Host " [$(Get-Date -Format dd)-$(Get-Date -Format MM)-$(Get-Date -Format yyyy) @ $(Get-Date -Format HH):$(Get-Date -Format mm):$(Get-Date -Format ss)]"
$updatesCollection = New-Object -ComObject Microsoft.Update.UpdateColl
if ( $update.EulaAccepted -eq 0 ) { $update.AcceptEula() }
$updatesCollection.Add($update) | out-null
# Download
$number++
$size = $update.MaxDownloadSize/1MB
$size = "{0:N2}" -f $size
$totalDownloaded = $totalDownloaded + $size
Write-Host " + Downloading $number of $($updates.count) - $size MB:" $($update.Title)
$sw.Reset();$sw.Start()
$updatesDownloader = $updateSession.CreateUpdateDownloader()
$updatesDownloader.Updates = $updatesCollection
$downloadResult = $updatesDownloader.Download()
$sw.Stop()
$message = " - Download {0}" -f (Get-WIAStatusValue $downloadResult.ResultCode)
if($sw.Elapsed.Seconds -lt 1){Write-Host $message "in less than 1 second"}else{Write-Host $message "in $($sw.Elapsed.Hours)h$($sw.Elapsed.Minutes)m$($sw.Elapsed.Seconds)s"}
# Install
Write-Host " - Installing update"
$sw.Reset();$sw.Start()
$updatesInstaller = $updateSession.CreateUpdateInstaller()
$updatesInstaller.Updates = $updatesCollection
$installResult = $updatesInstaller.Install()
$sw.Stop()
$message = " - Install {0}" -f (Get-WIAStatusValue $downloadResult.ResultCode)
if($sw.Elapsed.Seconds -lt 1){Write-Host $message "in less than 1 second"}else{Write-Host $message "in $($sw.Elapsed.Hours)h$($sw.Elapsed.Minutes)m$($sw.Elapsed.Seconds)s"}
Write-Host
$needsReboot = $installResult.rebootRequired
}
if($needsReboot){Write-Host " One or more updates require a reboot to complete installation" -foregroundcolor "red"}

$runTime.Stop()
Write-Host -foregroundColor yellow "`n $totalDownloaded MB of updates downloaded and installed in $($runTime.Elapsed.Hours) hour(s) $($runTime.Elapsed.Minutes) minute(s) $($runTime.Elapsed.Seconds) second(s)."