How To Backup And Restore IIS 7 Metabase With PowerShell
As I mentioned in my last blog post I've been playing around with PowerShell for SharePoint automation for a while now. One of the problems with SharePoint is it's complicated architecture that makes a seemingly simple task - backing up the system - incredibly complicated. The complexity often comes from the fact that there are so many options to choose from. There are SQL backups of the content databases, Stsadm.exe backups of whole or parts of the farm, VMWare snapshots of the server (which by the way is not supported by Microsoft), file backups of the 12 hive, solution file backups, web.config backups, IIS backups, third party backup solutions that do some or all of these things etc. etc. etc.
This blog post is not going to solve those issues for you, but it will at least give you one part of the puzzle: how to backup and restore the IIS metabase with PowerShell.
# This function performs a backup of the IIS Metabase
function SP-Backup-IIS {
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
[string]
$BackupFolder
)
process {
UI-PrintAction "Attempting to backup the Internet Information Services Metabase"
Write-Host "Checking IIS version..."
Write-Host
$IISVersion = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\InetStp | select SetupString, *Version*)
Write-Host "IIS Version:"
$IISVersion
Write-Host
$ComputerName = Get-Content Env:Computername
$Time = [DateTime]::Now.ToString().Replace(":",".").Replace(" ","_")
$BackupName = "IIS-Metadata-$ComputerName-$Time"
$BackupFileName = "$BackupName.zip"
switch ($IISVersion.MajorVersion)
{
# IIS 7
7 {
$BackupFilePath = Join-Path -Path $BackupFolder -ChildPath $BackupFileName
Write-Host "Starting backup of IIS metadata."
Write-Host
#Perform backup
& $env:windir\system32\inetsrv\appcmd.exe add backup $BackupName
#Zip and copy backup to destination
$IISRootBackupFolder = Get-Item $env:windir\system32\inetsrv\backup
$IISBackupFolder = Join-Path -Path $IISRootBackupFolder -ChildPath $BackupName
Zip-Compress-Folder $IISBackupFolder $BackupFilePath
Write-Host "Backup Complete"
}
# Other version of IIS
default { Write-Host "This version of IIS is not supported in this script." -ForegroundColor Yellow }
}
Write-Host
}
}
# This function restores a backup of the IIS Metabase
function SP-Restore-IIS {
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
[string]
$BackupName
)
process {
UI-PrintAction "Attempting to restore the Internet Information Services Metabase"
Write-Host "Checking IIS version..."
Write-Host
$IISVersion = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\InetStp | select SetupString, *Version*)
Write-Host "IIS Version:"
$IISVersion
Write-Host
switch ($IISVersion.MajorVersion)
{
# IIS 7
7 {
Write-Host "Starting restore of IIS metadata."
Write-Host
#Perform restore
& $env:windir\system32\inetsrv\appcmd.exe restore backup $BackupName
Write-Host
Write-Host "Restore Complete"
}
#Other version of IIS
default { Write-Host "This version of IIS is not supported in this script." -ForegroundColor Yellow }
}
Write-Host
}
}
# This function zips the contents of a folder
function Zip-Compress-Folder {
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
[string]
$SourceFolder,
[Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=1)]
[string]
$ZipFileName
)
process {
Write-Host
Write-Host "Creating new zip file."
Write-Host
Write-Host "Source: $SourceFolder"
Write-Host "Destination: $ZipFileName"
Write-Host
$ParentFolder = (Get-Item $SourceFolder).Parent.FullName
# Check if file exists
if (test-path $ZipFileName) {
Write-Host "The file $ZipFileName already exists." -ForegroundColor Yellow
return
}
# Create zip file
Set-Content $ZipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(Dir $ZipFileName).IsReadOnly = $false
$ZipFile = (New-Object -com shell.application).NameSpace($ZipFileName)
Write-Host "Adding $SourceFolder to the zip file."
Write-Host
$ZipFile.CopyHere((Get-Item $SourceFolder).FullName)
Write-Host "Zip file created."
Write-Host
}
}
SP-Backup-IIS will backup the IIS metabase, zip the backup folder and copy it to the location you specify in the $BackupFolder parameter. The SP-Restore-IIS will restore the IIS metabase from the backup you specify in the $BackupName parameter. This parameter corresponds to the name of the backup folder in 'C:\Windows\System32\inetsrv\backup'. You could expand on this by having the restore script first get your zip file and extract it to the backup folder. Happy scripting!











May 19th, 2011 - 20:07
So I added the value:
$BackupFolder = “C:\Backups\IIS”
However, when I run the script, nothing happens. I have set the execution policy to unrestricted.
I am using Powershell 2.0, W2k8R2, running it inside the PowerShell ISE.
Any ideas?
May 20th, 2011 - 16:46
This is what I have now…….
# This function performs a backup of the IIS Metabase
function SP-Backup-IIS {
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
[string]$BackupFolder
)
process {
$ComputerName = Get-Content Env:Computername
$Time = [DateTime]::Now.ToString().Replace(“:”,”.”).Replace(” “,”_”)
$BackupName = “IIS-Metadata-$ComputerName-$Time”
$BackupFileName = “$BackupName.zip”
$BackupFilePath = Join-Path -Path $BackupFolder -ChildPath $BackupFileName
Write-Host “Starting backup of IIS metadata.”
Write-Host
#Perform backup
& $env:windir\system32\inetsrv\appcmd.exe add backup $BackupName
#Zip and copy backup to destination
$IISRootBackupFolder = Get-Item $env:windir\system32\inetsrv\backup
$IISBackupFolder = Join-Path -Path $IISRootBackupFolder -ChildPath $BackupName
Zip-Compress-Folder $IISBackupFolder $BackupFilePath
Write-Host “Backup Complete”
}
}
SP-Backup-IIS
This is the output:
Join-Path : Cannot find drive. A drive with the name ‘”C’ does not exist.
At C:\IIS_Backup.ps1:19 char:32
+ $BackupFilePath = Join-Path <<<< -Path $BackupFolder -ChildPath $BackupFileName
+ CategoryInfo : ObjectNotFound: ("C:String) [Join-Path], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.JoinPathCommand
May 20th, 2011 - 16:47
I get the above after I enter “C:\Backups\IIS” when I get the prompt to enter a value for $BackupFolder
May 20th, 2011 - 20:45
Here was the problem:
[DateTime]::Now.ToString().Replace(“:”,”.”).Replace(” “,”_”)
Output:
5/20/2011_12.54.34_PM
$Time = [DateTime]::Now.ToString().Replace(“/”,”.”).Replace(“:”,”.”).Replace(” “,”_”)
Output:
5.20.2011_12.54.34_PM
Hence now it can save the file with that file name format.
Thanks.
May 21st, 2011 - 15:06
Hi Jason,
I knew that Replace() hack would come back and bite me in the ass!=) It’s obviously returning the time and date according to your regional settings. On my machine that would be 20.05.2011 12:54:34, and because ‘:’ is not a legal filename character I replaced it with a ‘.’
I guess it would be better to build the filename from scratch rather than to rely on the output of the DateTime.ToString() method.
Thank you very much for pointing this out!
-Olav