Compare two CSV files to trend mailbox growth

I had an interesting request the other day. A co-worker had two CSV files containing mailbox information from the same Exchange server, but from different parts of the day. He wanted to know if there was any way to find which users had the most growth in their mailbox size.

Here is an example of how to get mailbox size for all users on the same Exchange server:

Get-MailboxStatistics -Server EXCHANGE01 | 
Select-Object -Property DisplayName, 
@{N="SizeMB";E={$_.TotalItemSize.Value.ToMB()}}, Identity | 
Export-Csv file2.csv -NoTypeInformation

The first thought that came to mind had involved Group-Object and Measure-Object. I threw something together that got the job done, but decided to clean it up a bit and thought I’d share it here.
[cc lang=”powershell”]
Import-Csv file1.csv, file2.csv | Group-Object -Property Identity | %{
$thisDetail = $_ | Select-Object -ExpandProperty Group| Measure-Object SizeMB -Maximum -Minimum
New-Object psobject -Property @{
DisplayName = [string]($_.Group[0].DisplayName)
GrowthMB = [float]($thisDetail.Maximum – $thisDetail.Minimum)
} | Select DisplayName, GrowthMB
} | Sort-Object GrowthMB -Descending | Select-Object -First 10
[/cc]

Hope someone else finds this helpful!

Posted in Messaging, Scripting | Leave a comment

PowerCLI checks for vSphere Datastores

Over the last couple of days, I have posted a handful of PowerCLI scripts to check a vSphere environment. These checks have looked at general cluster level reporting, networking and virtual machines. Today I’m posting a couple of checks that look at datastores. I hope you find these checks useful.

In my environment, local disks contain the text boot or local. The following code will return a list of non-shared datastores that do not follow this naming convention. This could indicate local disk that doesn’t follow a standard naming convention.
[cc lang=”powershell”]
Get-View -ViewType Datastore -Property Name, Summary |
?{$_.Summary.MultipleHostAccess -eq $false -And $_.Name -notmatch “boot|local”} |
Select Name, @{N=”Datastore Type”;E={$_.Summary.Type}},
@{N=”Capacity (GB)”;E={[math]::round( $_.Summary.Capacity/1GB , 0)}} |
Sort-Object Name
[/cc]

The following script will return a list of datastores reporting as not accessible. I’ve seen this happen after removing datastores from hosts where array based snapshots had been previously presented. Typically an HBA re-scan will clear up this issue.
[cc lang=”powershell”]
Get-View -ViewType Datastore -Property Name, Summary |
?{$_.Summary.Accessible -eq $false} |
Select-Object name, @{N=”Datastore Type”;E={$_.Summary.Type}},
@{N=”Capacity (GB)”;E={[math]::round( $_.Summary.Capacity/1GB , 0)}} |
Sort-Object Name
[/cc]

I try to keep the VMFS block size and version consistent on all shared storage in my environment. The following code will show VMFS datastores if inconsistent block sizes or VMFS versions are not using the most common configuration detected in the environment.
[cc lang=”powershell”]
$vmfsDs = Get-View -ViewType Datastore -Property Name, Summary, Info, Host |
?{$_.Summary.Type -eq ‘VMFS’ -and $_.Summary.MultipleHostAccess -eq $true} |
Select-Object Name, @{N=”VMFS Version”;E={$_.Info.Vmfs.Version}},
@{N=”Block Size (MB)”;E={$_.Info.Vmfs.BlockSizeMB}},
@{N=”Host Count”;E={@($_.Host).Count}}

if ( ($vmfsDs | Select-Object -Property “Block Size (MB)” -Unique | Measure-Object).Count -gt 1 -or
($vmfsDs | Select-Object -Property “VMFS Version” -Unique | Measure-Object).Count -gt 1) {
$standardVmfsBlockSize = (($vmfsDs | Group-Object -Property “Block Size (MB)”) | Sort-Object Count -Descending | Select-Object -First 1).Name
$standardVmfsVersion = (($vmfsDs | Group-Object -Property “VMFS Version”) | Sort-Object Count -Descending | Select-Object -First 1).Name
$vmfsDs | ?{$_.”Block Size (MB)” -ne $standardVmfsBlockSize -or $_.”VMFS Version” -ne $standardVmfsVersion } |
Sort-Object Name
}
[/cc]

I hope someone else finds these checks useful.

Posted in Scripting, Virtualization | Leave a comment

vSphere virtual machine checks

I’ve recently posted a series of vSphere checks based on PowerCLI. The following couple of checks apply to virtual machines.

The following check looks for virtual machines where the ‘toolsUpgradePolicy’ is set to manual. I like to change this value to ‘upgradeAtPowerCycle’ which causes virtual machines (which are already running tools) to check for an update tools automatically at reboot.
[cc lang=”Powershell”]
Get-View -ViewType VirtualMachine -Property Name, “Config.Tools.toolsUpgradePolicy”,”Guest.ToolsVersionStatus” -Filter @{“Config.Tools.toolsUpgradePolicy”=”manual”} |
Select Name, @{N=”Tools Status”;E={$_.Guest.ToolsVersionStatus}},@{N=”Upgrade Policy”;E={$_.Config.Tools.toolsUpgradePolicy}} |
Sort Name
[/cc]

The following check is one that has caused some discussion with my peers. I can’t find a specific KB article that references this issue, but rumor has it that a Windows virtual machine on a port group with 10GbE uplinks requires a minimum of 1GB of RAM to provide heap space for the network card driver in the guest. To keep this script simple, it simply checks for the fastest link speed uplink on a host, and if greater than 10,000 verifies that all of the virtual machines have at least 1GB of RAM. Since this is rumor I can’t prove that the issue exists — or only exists for Windows guests — all virtual machines on hosts that have 10Gbps uplinks appear on this report. If you have any proof on this issue, or just want to throw in your two cents, please feel free to leave a comment.
[cc lang=”powershell”]
$vmLessThan1GB = @()
Get-View -ViewType HostSystem -Property Name, “Config.Network.Pnic” | %{
$thisHost = $_
$thisHostMaxSpeed = ($_.config.network.pnic | Select @{Name=”SpeedMB”; Exp={ $_.LinkSpeed.SpeedMb } } | sort SpeedMB -Descending | Select -First 1).SpeedMB
if ($thisHostMaxSpeed -ge 10000) {

$vmLessThan1GB += Get-View -ViewType virtualmachine -Property Name, “Config.Hardware.MemoryMB”, “Runtime.Host.Value” -Filter @{“Runtime.Host”=”^$($thisHost.MoRef.Value)$”} |
?{$_.Config.Hardware.MemoryMB -lt 1024} |
Select Name, @{N=”VM RAM (MB)”;E={$_.Config.Hardware.MemoryMB}}, @{N=”VM Host Name”;E={$thisHost.Name}}, @{N=”Max NIC Speed”;E={$thisHostMaxSpeed}}
}
}
$vmLessThan1GB | Sort Name
[/cc]

Posted in Scripting, Virtualization | Leave a comment

Quick vSphere Cluster BIOS check

The following check will compare the BIOS versions of the ESX hosts in a cluster and verify they are all at a consistent level.

The check makes use of a $Clusters variable, which can be created using the following line of code:

$clusters = Get-Cluster

This check will look for inconsistent BIOS versions between hosts in a vSphere cluster.
[cc lang=”powershell”]
$misMatchBios = @()
$Clusters | select Name, ID | %{
$thisClusterName = $_.Name
$thisClusterBIOS = Get-View -ViewType HostSystem -SearchRoot $_.id -Property Name, “Hardware.BiosInfo” | Select Name,@{N=”Cluster Name”;E={$thisClusterName}},@{N=”BIOS version”;E={$_.Hardware.BiosInfo.BiosVersion}}, @{N=”BIOS date”;E={$_.Hardware.BiosInfo.releaseDate}}
$thisClusterBiosGroup = $thisClusterBIOS | Group-Object -Property “BIOS Version”

if ( ($thisClusterBiosGroup | Measure-Object).Count -gt 1 ) { $misMatchBios += ( $thisClusterBIOS | Sort Name ) }
}
$misMatchBios
[/cc]

Posted in Scripting, Virtualization | Leave a comment

Network related vSphere checks

The following two sections of code can be ran independently or used in conjunction with Alan Renouf’s vCheck script. They return network specific issues that could happen in a vSphere environment.

The first check makes use of a $clusters variable, which can be created using the following line of code:

$Clusters = Get-Cluster

The following section will report on any port groups that do not exist on all hosts in a cluster. This is a fairly common issue with standard vSwitches, but is typically resolved by using Distributed vSwitches (for the Enterprise Plus users).
[cc lang=”Powershell”]
$networkListHT = @{}
Get-View -ViewType Network -Property Name | %{ $networkListHT.Add($_.MoRef.value,$_.Name) }

$portGroupCheck = @()
$Clusters | Select Name, ID | %{
$thisClusterName = $_.Name
$thisClusterHosts = Get-View -ViewType HostSystem -SearchRoot $_.id -Property Name, Network

$thisClusterNetworks = @()
$thisClusterHosts | %{
$thisHost = $_.Name
$_.Network | %{ $thisClusterNetworks += New-Object psobject -Property @{ “Port Group”=$networkListHT[$_.Value]; Host=$thisHost; Cluster=$thisClusterName} }
}

$portGroupCheck += ($thisClusterNetworks | Group-Object -Property “Port Group” | ?{$_.Count -lt $thisClusterHosts.count} | Select -ExpandProperty Group | Sort Host )
}

$portGroupCheck
[/cc]

The following one liner will show any port group that does not have virtual machines. This could be a new network that simply doesn’t have VMs yet, or an old network that is no longer required.
[cc lang=”powershell”]
Get-View -ViewType Network -Property Name, VM, Host |?{@($_.VM).Count -eq 0} | Select Name, @{Name=”Host Count”; Expression={@($_.Host).Count}} | Sort Name
[/cc]

Posted in Scripting, Virtualization | Leave a comment