VCP5 – vSphere 5 Configuration Maximums Quiz in PowerShell
I've been learning my vSphere 5 config maximums before my upcoming VCP5 exam, so in a supreme effort of procrastination I thought I'd write a PowerShell quiz script: here it is!
Save the QuizMe.ps1 file into a folder and then place one or more text file in the same folder containing a comma delimited set of questions and answers. Then run QuizMe.ps1!
SCOM 2007 R2: Daily Health Check Script
An updated version of this script has been released: http://www.definit.co.uk/2012/05/scom-2007-r2-daily-health-check-script-v2/
I've been working with a Microsft SCOM PFE (Premier Field Engineer) for the last few months and part of the engagement is an environment health check for the SCOM setup. Based on this Microsoft recommend a series of health checks to for the environment that should be carried out every day. This is summarised as the following:
- Check the health of all Management Servers and Gateways
- Check the RMS is not in maintenance mode
- Review Outstanding Alerts
- Review Agent's Health Status
- Review Backup Status
- Review any Management Group Alerts
- Review the Pending Management status
- Review Database Sizes (Operations, Data warehouse, ACS)
- Review Volume of Alerts
- Review Alert Latency
- Document any changes
VMware PowerCLI – Set Path Selection Policy on all LUNs for a host
Just a quick script to set the Path Selection Policy on any LUNs on a host that do not have your target policy enabled. The script sets the server to Maintenance mode first, evacuating any VMs if you are in a full DRS automated environment. While this is not strictly necessary, it was required for my production environment just to be safe.
param( [string] $vCenterServer = $(Read-Host -prompt "Enter vCenter Server Name"),
[string] $TargetPolicy = $(Read-Host -Prompt "Enter target policy (RoundRobin, Fixed or MostRecentlyUsed)"),
[string] $TargetHost = $(Read-Host -Prompt "Enter target Host"),
[switch] $WhatIf)
# Add the VI-Snapin if it isn't loaded already
if ((Get-PSSnapin -Name "VMware.VimAutomation.Core" -ErrorAction SilentlyContinue) -eq $null ) {Add-PSSnapin -Name "VMware.VimAutomation.Core"}
Connect-VIServer $vCenterServer | out-null
Write-Host "Connected to: " $vCenterServer -ForegroundColor Green
Write-Host "Target PSP: " $TargetPolicy -ForegroundColor Yellow
Write-Host
switch ($TargetPolicy) {
RoundRobin { $DisplayPolicy = "VMW_PSP_RR"; }
MostRecentlyUsed { $DisplayPolicy = "VMW_PSP_MRU"; }
Fixed { $DisplayPolicy = "VMW_PSP_FIXED"; }
default { Write-Warning "Unknown PSP selected! Please consult the help and try again."; exit }
}
Write-Host "Setting Policy to"$TargetPolicy" on "$TargetHost -ForegroundColor Green
if($WhatIf) {
$vHost = Get-VMHost -Name $TargetHost
$vHost | Set-VMHost -State Maintenance -Evacuate -WhatIf
$vHost | Get-ScsiLun -LunType "disk" -ErrorAction SilentlyContinue | where {$_.IsLocal -eq $false -and $_.MultipathPolicy -ne $TargetPolicy} | Set-ScsiLun -MultipathPolicy $TargetPolicy -WhatIf
$vHost | Set-VMHost -State Connected -WhatIf
} else {
$vHost = Get-VMHost -Name $TargetHost
Write-Host "Setting "$TargetHost" to Maintenance Mode" -ForegroundColor White
$vHost | Set-VMHost -State Maintenance -Evacuate
$vHost | Get-ScsiLun -LunType "disk" -ErrorAction SilentlyContinue | where {$_.IsLocal -eq $false -and $_.MultipathPolicy -ne $TargetPolicy} | Set-ScsiLun -MultipathPolicy $TargetPolicy
Write-Host "Exiting Maintenance mode on"$TargetHost -ForegroundColor White
$vHost | Set-VMHost -State Connected
}
SCOM 2007 DFS Backlog Monitoring – Distributing a RunAs account to only DFS replication members
The DFS monitoring tool in SCOM 2007 has some great features, which will replace many a custom VB script running in enterprises. As with a lot of Management Packs, to get the most out of it you need to have a dedicated RunAs account with local admin permissions on the servers you are monitoring (e.g. for the Backlogged Files reporting).
The easy (and wrong) option here is to go with the less secure option and distribute a RunAs account to ALL servers. There are lots of reasons why you wouldn’t want to distribute the credentials to every server in your SCOM installation – but just from a security standpoint, you shouldn’t do it! Selecting the “More Secure” option and distributing credentials only to servers which will require them is a much safer bet.
You can view the members of the DFS discovered inventory in the SCOM Console by going to the “Discovered Inventory” view and changing the target type to “Replication Member” – which is great: you can see all the Servers involved in the DFS replication topology. But there’s no easy way to add these to a RunAs credential to distribute.
To narrow it down to a short list, you can open a Operation Manager Shell prompt and list any monitoring classes which have “DFS” in the name – there are about 6 or so:
Get-MonitoringClass | where {$_.Name –match “DFS”}
The one that matches my SCOM console view is “Microsoft.Windows.DfsReplication.ReplicationGroupMember” so I want to select all the monitoring-objects that match this discovery and export the “Path” (server name) to a csv file:
Get-MonitoringClass | where {$_.Name –match “Microsoft.Windows.DfsReplication.ReplicationGroupMember”} | get-monitoringobject | select-object Path | export-csv c:\DFS-Members.csv
I’ve not yet figured out how to add these to the RunAs account credential distribution via PowerShell, so I’m afraid it’s a manual process from here. To make it easier I opened the csv in Excel and filtered out duplicates (for servers with multiple DFS shares) before pasting the servers in individually to the distribution dialogue.
Once the RunAs account has been downloaded by the Agents, and if you've added it correctly to your "DFS Replication Monitoring Account" profile, you should start to see the Backlog Monitoring view beginning to populate.
Exchange 2010 – CreateTestUser : Mailbox could not be created. Verify that OU ( Users ) exists and that password meets complexity requirements
While using the New-TestCasConnectivityUser.ps1 script to create a test user for Exchange 2010’s connectivity testing, I ran into an issue:
CreateTestUser : Mailbox could not be created. Verify that OU ( Users ) exists and that password meets complexity requirements.
At C:\Program Files\Microsoft\Exchange Server\V14\Scripts\new-TestCasConnectivityUser.ps1:255 char:27
+ $result = CreateTestUser <<<< $exchangeServer $mailboxServer $securePassword $OrganizationalUnit $UMDialPlan $UMExtension $Prompt
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,CreateTestUser
Oddly enough, that OU does exist (as it will by default on any Windows Domain!) and the password complexity more than satisfied the complexity requirements. The issue is simple enough to fix, I opened the script in notepad and found the line beginning “new-mailbox” – and deleted the parameter “–OrgainisationalUnit:$OrganistationalUnit”. This means the new user defaults to the default OU – Users!
Just a simple fix to save some time! Thanks MS for the buggy script!
Update: Looks like this occurs when there's more than one OU called Users - my fix will still sort it, but at least you know!
Reporting all ActiveSync devices and their Users in Exchange 2010
Recently I needed to report on the ActiveSync devices that were attached to our Exchange 2010 organisation, and which users they were accessing, and then export them to a CSV file.
Using PowerShell to add IP addresses to IIS7’s FTP IPv4 Address and Domain Restrictions
Today I was configuring a new FTP server based on IIS7 (well, 7.5 technically as it’s a Server 2008 R2 host), and I wanted an easy way to add and remove allowed IP addresses based on either an XML config file or a CSV import. Customers’ IP addresses are added or removed regularly, but I didn’t want to have to update their details twice, once on the server and once in the documents.
Configuring Server 2008 R2 Core Series: Installing and Managing IIS
So, you’ve installed a new server with Server 2008 R2 Core – what next? Logging on, you’re presented with a shiny command prompt, you can run notepad or regedit…but aside from that, where do you go from there? In the next few series of posts I’ll hopefully point out the basics, and some not so basics!
In this post, I’m covering Installing the IIS web server (and a few useful bits) and managing it from the IIS Management Snap-in.
Installing the basic IIS installation
Installing optional components in Server 2008 R2 Core is handled by two commands, OCList and OCSetup. OCList, as the name suggests, lists the optional components and their status, installed or not installed. It’s a long list, so I recommend issuing the command with the “|more” pipe:
oclist | more
The output looks something like this:
OCSetup will accept any one, or multiple, of the roles listed in OCList as an argument to install. It’s recommended you use the command with “start /w” preceding so that the command prompt will wait for the installation to finish before continuing.
To install the basic IIS web server install, use
start /w ocsetup IIS-WebServerRole
As far as I can see, this installs the roles:
Installed:IIS-WebServerRole
Installed:IIS-WebServer
Installed:IIS-ApplicationDevelopment
Installed:IIS-CommonHttpFeatures
Installed:IIS-DefaultDocument
Installed:IIS-DirectoryBrowsing
Installed:IIS-HttpErrors
Installed:IIS-StaticContent
Installed:IIS-HealthAndDiagnostics
Installed:IIS-HttpLogging
Installed:IIS-Performance
Installed:IIS-HttpCompressionStatic
Installed:IIS-Security
Installed:IIS-RequestFiltering
Installed:IIS-WebServerManagementTools
In order to get .Net functioning and allow remote management, you’ll also need the following components installed, a registry key added and the Web Management Service Started (in order):
start /w ocsetup WAS-NetFxEnvironment start /w ocsetup IIS-ISAPIExtensions start /w ocsetup IIS-ISAPIFilter start /w ocsetup IIS-NetFxExtensibility start /w ocsetup IIS-ASPNET start /w ocsetup IIS-ManagementService reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WebManagement\Server /v EnableRemoteManagement /t REG_DWORD /d 1 net start wmsvc
You should now be able to manage your IIS server via the IIS Management Console on a Windows Server 2008 or Windows 7 PC with Remote Server Administration Tools installed.
You can also manage IIS through a PowerShell addin, if you run powershell.exe on your Server Core installation, then import the WebAdministration Module:
C:\Users\Administrator>powershell Windows PowerShell Copyright (C) 2009 Microsoft Corporation. All rights reserved. PS C:\Users\Administrator> Import-Module WebAdministration PS C:\Users\Administrator> Get-Command -PsSnapin WebAdministration CommandType Name Definition ----------- ---- ---------- Cmdlet Add-WebConfiguration Add-WebConfiguration [-Filte... Cmdlet Add-WebConfigurationLock Add-WebConfigurationLock [-F... Cmdlet Add-WebConfigurationProperty Add-WebConfigurationProperty... Cmdlet Backup-WebConfiguration Backup-WebConfiguration [-Na... Alias Begin-WebCommitDelay Start-WebCommitDelay Cmdlet Clear-WebConfiguration Clear-WebConfiguration [-Fil... Cmdlet Clear-WebRequestTracingSettings Clear-WebRequestTracingSetti... Cmdlet ConvertTo-WebApplication ConvertTo-WebApplication [[-... Cmdlet Disable-WebGlobalModule Disable-WebGlobalModule [-Na... Cmdlet Disable-WebRequestTracing Disable-WebRequestTracing [[... Cmdlet Enable-WebGlobalModule Enable-WebGlobalModule [-Nam... Cmdlet Enable-WebRequestTracing Enable-WebRequestTracing [[-... Alias End-WebCommitDelay Stop-WebCommitDelay Cmdlet Get-WebAppDomain Get-WebAppDomain [-InputObje... Cmdlet Get-WebApplication Get-WebApplication [[-Name] ... Cmdlet Get-WebAppPoolState Get-WebAppPoolState [[-Name]... Cmdlet Get-WebBinding Get-WebBinding [[-Name] <Str... Cmdlet Get-WebConfigFile Get-WebConfigFile [[-PSPath]... Cmdlet Get-WebConfiguration Get-WebConfiguration [-Filte... Cmdlet Get-WebConfigurationBackup Get-WebConfigurationBackup [... Cmdlet Get-WebConfigurationLocation Get-WebConfigurationLocation... Cmdlet Get-WebConfigurationLock Get-WebConfigurationLock [-F... Cmdlet Get-WebConfigurationProperty Get-WebConfigurationProperty... Cmdlet Get-WebFilePath Get-WebFilePath [[-PSPath] <... Cmdlet Get-WebGlobalModule Get-WebGlobalModule [[-Name]... Cmdlet Get-WebHandler Get-WebHandler [[-Name] <Str... Cmdlet Get-WebItemState Get-WebItemState [[-PSPath] ... Cmdlet Get-WebManagedModule Get-WebManagedModule [[-Name... Cmdlet Get-WebRequest Get-WebRequest [-InputObject... Cmdlet Get-Website Get-Website [[-Name] <String... Cmdlet Get-WebsiteState Get-WebsiteState [[-Name] <S... Cmdlet Get-WebURL Get-WebURL [[-PSPath] <Strin... Cmdlet Get-WebVirtualDirectory Get-WebVirtualDirectory [[-N... Function IIS: set-location IIS: Cmdlet New-WebApplication New-WebApplication [-Name] <... Cmdlet New-WebAppPool New-WebAppPool [-Name] <Stri... Cmdlet New-WebBinding New-WebBinding [[-Name] <Str... Cmdlet New-WebFtpSite New-WebFtpSite [-Name] <Stri... Cmdlet New-WebGlobalModule New-WebGlobalModule [-Name] ... Cmdlet New-WebHandler New-WebHandler [-Name] <Stri... Cmdlet New-WebManagedModule New-WebManagedModule [-Name]... Cmdlet New-Website New-Website [-Name] <String>... Cmdlet New-WebVirtualDirectory New-WebVirtualDirectory [-Na... Cmdlet Remove-WebApplication Remove-WebApplication [-Name... Cmdlet Remove-WebAppPool Remove-WebAppPool [-Name] <S... Cmdlet Remove-WebBinding Remove-WebBinding [-Protocol... Cmdlet Remove-WebConfigurationBackup Remove-WebConfigurationBacku... Cmdlet Remove-WebConfigurationLocation Remove-WebConfigurationLocat... Cmdlet Remove-WebConfigurationLock Remove-WebConfigurationLock ... Cmdlet Remove-WebConfigurationProperty Remove-WebConfigurationPrope... Cmdlet Remove-WebGlobalModule Remove-WebGlobalModule [-Nam... Cmdlet Remove-WebHandler Remove-WebHandler [-Name] <S... Cmdlet Remove-WebManagedModule Remove-WebManagedModule [-Na... Cmdlet Remove-Website Remove-Website [-Name] <Stri... Cmdlet Remove-WebVirtualDirectory Remove-WebVirtualDirectory [... Cmdlet Rename-WebConfigurationLocation Rename-WebConfigurationLocat... Cmdlet Restart-WebAppPool Restart-WebAppPool [[-Name] ... Cmdlet Restart-WebItem Restart-WebItem [[-PSPath] <... Cmdlet Restore-WebConfiguration Restore-WebConfiguration [-N... Cmdlet Select-WebConfiguration Select-WebConfiguration [-Fi... Cmdlet Set-WebBinding Set-WebBinding [[-Name] <Str... Cmdlet Set-WebConfiguration Set-WebConfiguration [-Filte... Cmdlet Set-WebConfigurationProperty Set-WebConfigurationProperty... Cmdlet Set-WebGlobalModule Set-WebGlobalModule [-Name] ... Cmdlet Set-WebHandler Set-WebHandler [-Name] <Stri... Cmdlet Set-WebManagedModule Set-WebManagedModule [-Name]... Cmdlet Start-WebAppPool Start-WebAppPool [[-Name] <S... Cmdlet Start-WebCommitDelay Start-WebCommitDelay [-Verbo... Cmdlet Start-WebItem Start-WebItem [[-PSPath] <St... Cmdlet Start-Website Start-Website [[-Name] <Stri... Cmdlet Stop-WebAppPool Stop-WebAppPool [[-Name] <St... Cmdlet Stop-WebCommitDelay Stop-WebCommitDelay [[-PSPat... Cmdlet Stop-WebItem Stop-WebItem [[-PSPath] <Str... Cmdlet Stop-Website Stop-Website [[-Name] <Strin...
Serve up a .NET page, to taste
Not that you’d doubt me (!) but there’s one last thing to do - prove it worked. Fortunately, there’s an easy way to do that. I borrowed the code from www.codefixer.com to create a little “hello world” page. Since the default website is c:\inetpub\wwwroot\ I saved the page there as default.aspx and fired up my browser – et voila!
Powershell script to zip all .bak files in a folder structure, then delete the .bak
Our development SQL server is a monster...there are many many databases, and hundreds, if not thousands of backup files. With each patch tested on the software we sell, there is a new backup. With each client deployment, a new database. With each new major version, a new database. Backups of the new databases inevitably occur, and so we have more files, in more folders - most of which need to be kept in case of roll-backs, bugs or deployment issues.
This all adds up to a bit of an administrative nightmare, especially since the backups eat away at my storage at a phenomonal rate. Zipping the .bak files is great, but since each DB has it's own backup folder, it can become a bit of a nightmare to go through, zip and delete the .baks. For my first real foray into using PowerShell, I decided I'd write a script to take the legwork out of it for me.
# Powershell Script to recurse input path looking for .bak files, Zip them
# and delete the .bak.
function out-zip {
Param([string]$path)
if (-not $path.EndsWith('.zip')) {$path += '.zip'}
if (-not (test-path $path)) {
set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
}
$ZipFile = (new-object -com shell.application).NameSpace($path)
$input | foreach {$zipfile.CopyHere($_.fullname)} | out-null
}
$FileCount =0
$FilesZipped =0
$FilesDeleted =0
$InputPath = $args[0]
if($InputPath.Length -lt 2)
{
Write-Host "Please supply a path name as your first argument" -foregroundcolor Red
return
}
if(-not (Test-Path $InputPath))
{
Write-Host "Path does not appear to be valid" -foregroundcolor Red
return
}
$BakFiles = Get-ChildItem $InputPath -Include *.bak -recurse
Foreach ($Bak in $BakFiles)
{
write-host "File: $Bak" -foregroundcolor Yellow
$ZipFile = $Bak.FullName -replace ".bak", ".zip"
if (Test-Path $ZipFile)
{
Write-Host "$ZipFile exists already, aborted." -foregroundcolor Red
}
else
{
Get-Item $Bak | out-zip $ZipFile
if(Test-Path $ZipFile)
{
$Response = read-host -prompt "Please wait for zip to complete then type c<enter> to continue..."
if($Response = "c")
{
$FilesZipped++
Remove-Item $Bak.FullName
if(Test-Path $Bak.FullName)
{
Write-Host "File not deleted, manually remove $Bak.Fullname" -foregroundcolor Red
}
else
{
Write-Host "OK" -foregroundcolor Green
$FilesDeleted++
}
}
else
{
Write-Host "File delete aborted by user" -foregroundcolor Red
}
}
}
$FileCount++
}
Write-Host Files found: $FileCount
Write-Host Files Zipped: $FilesZipped
Write-Host Files Deleted: $FilesDeleted
Obviously, this is not something I'd recommend you running lightly without serious testing on your own systems - that said, I hope it helps! I make no warantee or any kind of promise that you won't lose data by running this! It's just an exercise in PowerShell for me.

