Gary's $this and that about PowerShell and Exchange

I am a Microsoft Senior Premier Field Engineer based out of Atlanta, GA. My focus is on Exchange Server and Powershell. This blog is mainly to share interesting Powershell script samples and tidbits about Exchange. I am a Microsoft Certified Master for
Blog - About

About $this blog:

I am a Microsoft Senior Premier Field Engineer based out of Atlanta, GA.  My focus is on Exchange Server and Powershell.  This blog is mainly to share interesting Powershell script samples and tidbits about Exchange.  I am a Microsoft Certified Master for Exchange Server 2007.

  • Gary's $this and that about PowerShell and Exchange

    Using Microsoft's New AD PowerShell Cmdlets

    • 0 Comments

    In the past two weeks I have really started playing with the new AD PowerShell cmdlets from Microsoft.  I am really glad these cmdlets are finally here.  I will admit though, to get them working in my lab, it was not easy.  I cant blame this though on the cmdlets themselves, as my problems stemmed from the fact that I don't have 64-bit virtualization capability yet in my own lab.

    To use the cmdlets you need to deal with the following 3 steps:

    1. You must have the cmdlets themselves, they are part of the ActiveDirectory module for PowerShell v2.  This module is a Windows Feature that can be installed ONLY on Windows 7 and Windows Server 2008 R2.  Life is super simple if you have a 2008 R2 Domain Controller, as you are good to go to import and use the module on that machine.  When you promote an R2 server to a DC, the AD PowerShell Module Windows feature is installed automatically (if its not it’s the same checkbox you use on Windows 7).  For Windows 7, you need to install the latest RSAT (Remote Server Admin Tools) and then add the Windows Feature for the PowerShell AD Module.  It appears that if you cant use Windows Server 2008 R2 or Windows 7, then you can not leverage these cmdlets right now (this means Windows Server 2008 (non-R2) as well).
    2. Once you have the module physically installed, you must import the module in your PowerShell v2 session.  This is as simple as typing PS C:\> Import-Module ActiveDirectory
    3. You must have an Active Directory Web Service (ADWS) Implemented on at least one of your Domain Controllers.  Any new 2008 R2 DC will have this new service.  If you haven't yet deployed a 2008 R2 DC, then you can install the ADWS on a down-level DC by installing the Active Directory Management Gateway Service.

    Once these three steps are in place you can then use the cmdlets.  You can see the cmdlets a few ways, but perhaps the easiest is to do this: PS C:\> Get-Command -Module ActiveDirectory

    By running the above cmdlet I found the following cmdlets:

    Add-ADComputerServiceAccount
    Add-ADDomainControllerPasswordReplicationPolicy
    Add-ADFineGrainedPasswordPolicySubject
    Add-ADGroupMember
    Add-ADPrincipalGroupMembership
    Clear-ADAccountExpiration
    Disable-ADAccount
    Disable-ADOptionalFeature
    Enable-ADAccount
    Enable-ADOptionalFeature
    Get-ADAccountAuthorizationGroup
    Get-ADAccountResultantPasswordReplicationPolicy
    Get-ADComputer
    Get-ADComputerServiceAccount
    Get-ADDefaultDomainPasswordPolicy
    Get-ADDomain
    Get-ADDomainController
    Get-ADDomainControllerPasswordReplicationPolicy
    Get-ADDomainControllerPasswordReplicationPolicyUsage
    Get-ADFineGrainedPasswordPolicy
    Get-ADFineGrainedPasswordPolicySubject
    Get-ADForest
    Get-ADGroup
    Get-ADGroupMember
    Get-ADObject
    Get-ADOptionalFeature
    Get-ADOrganizationalUnit
    Get-ADPrincipalGroupMembership
    Get-ADRootDSE
    Get-ADServiceAccount
    Get-ADUser
    Get-ADUserResultantPasswordPolicy
    Install-ADServiceAccount
    Move-ADDirectoryServer
    Move-ADDirectoryServerOperationMasterRole
    Move-ADObject
    New-ADComputer
    New-ADFineGrainedPasswordPolicy
    New-ADGroup
    New-ADObject
    New-ADOrganizationalUnit
    New-ADServiceAccount
    New-ADUser
    Remove-ADComputer
    Remove-ADComputerServiceAccount
    Remove-ADDomainControllerPasswordReplicationPolicy
    Remove-ADFineGrainedPasswordPolicy
    Remove-ADFineGrainedPasswordPolicySubject
    Remove-ADGroup
    Remove-ADGroupMember
    Remove-ADObject
    Remove-ADOrganizationalUnit
    Remove-ADPrincipalGroupMembership
    Remove-ADServiceAccount
    Remove-ADUser
    Rename-ADObject
    Reset-ADServiceAccountPassword
    Restore-ADObject
    Search-ADAccount
    Set-ADAccountControl
    Set-ADAccountExpiration
    Set-ADAccountPassword
    Set-ADComputer
    Set-ADDefaultDomainPasswordPolicy
    Set-ADDomain
    Set-ADDomainMode
    Set-ADFineGrainedPasswordPolicy
    Set-ADForest
    Set-ADForestMode
    Set-ADGroup
    Set-ADObject
    Set-ADOrganizationalUnit
    Set-ADServiceAccount
    Set-ADUser
    Uninstall-ADServiceAccount

     

    On the PowerShell Team Blog they posted a great write-up and a really nice graphic showing the cmdlets organized logically

    I hope this is a short and sweet guide to help get the cmdlets working for you!

    -Gary Siepser

     

    This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm.

  • Gary's $this and that about PowerShell and Exchange

    Mailbox Database Statistics

    • 0 Comments

    UPDATED: Minor Script Modifications made, detailed help comments added mainly for PSv2 and units added to property names

    First of all, let me apologize as I have been posting very much lately.  My plan with this blog was to post at least twice a week.  Obviously my posting has slowed way down.  I haven't at all lost interest in sharing with you, I just have run a bit low on ideas for the simpler, easier to write posts.  These days, the subjects I post about are tending to be more complex scripts and by their nature, they take a lot longer to write.  That being said, if anyone of the 3 of you out there reading this blog :) have any ideas for posts you would like to see, PLEASE comment on here or email me to ask for a post.  I need subjects to post about that I know there is interest to read about.

    Enough with the sob story…lets get to it.

    This post is about a script I wrote last night to generate some mailbox database statistics that I think will be useful to many out there.  I must thank Wayne Siegler as he was the inspiration for this script since he contacted me through this blog for help in writing something similar.  Thanks Wayne for asking, as it got to me write this and be able to share it with others.

    This script basically walks through your Exchange 2007 and above databases and gets their file size…but wait…there’s more.  I already posted a one-liner to do that.  This script though, then looks at the mailboxes on that database and generates stats about the total size of those mailboxes, the average size, and the max size.  As well it gives you counts.  It does this for all your databases and then at the end it simply looks at all the data its gathered so far and totals it all up to give you the org-wide stats.  Again though, this right now only works against Exchange 2007 and above DBs.  It could be modified to work against pre-Exchange 2007 DBs as well, but it would take a bit more code (the samples for what is needed can be found in others posts on this blog) and for now I want to keep the code a bit simpler.

    Folks, like all my posts, this is no production-level script.  I haven't built in any error checking, help information, parameters, etc. into this.  This is meant to be a demonstration of some techniques that can be used to get this data and output it as an object.

    Here is the code:

    #            .SYNOPSIS
    #           This script gather statistics about Mailbox Databases
    #
    #           .DESCRIPTION
    #           This script gathers the following database statistics about Exchange
    #            2007 and above mailbox databases:
    #           
    #              - Mailbox Count on Database
    #              - Database Physical FileSize
    #              - Total of Mailbox Sizes
    #             - Average Size of Mailboxes
    #             - Largest Mailbox on Database
    #            
    #            The script also totals the gathered statistics from all databases
    #            and adds the results to the end of the resultant array output.  This
    #            Script outputs a custom object to the success pipeline and its
    #            results can be piped to any typical cmdlet like export-csv or out-file
    #           
    #            This script was created by Gary Siepser of Microsoft.  This script is
    #            provided "AS IS" with no warranties, and confers no rights.  Use of
    #            any portion or all of this script are subject to the terms specified
    #            at http://www.microsoft.com/info/cpyright.htm.
    #   
    #           .INPUTS
    #           None. You cannot pipe objects to this script
    #
    #           .OUTPUTS
    #           PSCustomObject with NoteProperties for each of the statistics
    #
    #           .EXAMPLE
    #           C:\PS> .\script.ps1
    #           
    #            The script run alone will output in List format.
    #
    #           .EXAMPLE
    #           C:\PS> .\script.ps1 | Format-Table -Autosize
    #           
    #            This example will out a formatted table of the results.
    #
    #           .EXAMPLE
    #           C:\PS> .\script.ps1 | Export-Csv c:\export.csv
    #           
    #             This example will export the piplined object to a CSV file.
    #
    #           .EXAMPLE
    #           C:\PS> Get-Help .\script.ps1 -Full
    #           
    #             This example will retrieve the full help of this script.



    #Create an empty template object to be used as the blueprint of the final output objects
    $TemplateObject = New-Object PSObject |
    Select-Object DatabaseName,DatabaseFileSizeGB,TotalMailboxSizeGB,NumberofMailboxes,AverageMailboxSizeMB,MaxMailboxSizeMB


    #Create the empty array to hold the Output Results
    $ResultSet = @()

    #Retrieve all DB Objects and loop through them
    $databases = get-mailboxdatabase
    foreach ($DB in $databases)
    {
     
       
    #Create a copy of the Template
        $TempObject = $TemplateObject | Select-Object *
       
       
    #Get the DB File Size Info
        $DBRawFileInfo = get-wmiobject cim_datafile -computername $DB.server -filter ('name=''' + $DB.edbfilepath.pathname.replace("\","\\") + '''')
       
    $DBFileSize = [math]::Round([Decimal]( $DBRawFileInfo.filesize / 1GB),2)
       
       
    #Get Stats about the mailboxes in this database
        $AllMailboxstats = get-mailboxstatistics -database $DB.identity | Where-Object {$_.objectclass -eq "Mailbox"}
       
    $CombinedMailboxSizes = @()
       
    foreach ($mailbox in $AllMailboxstats)
        {
           
    $CombinedMailboxSizes += ($mailbox.totalitemsize.value.ToBytes() + $mailbox.totaldeleteditemsize.value.ToBytes())
        }
       
    $Stats = $CombinedMailboxSizes | Measure-Object -Average -Maximum -Sum
       
       
    #Save all this data we have into the template object
        $TempObject.DatabaseName = $DB.Name
       
    $TempObject.DatabaseFileSizeGB = $DBFileSize
       
    $TempObject.TotalMailboxSizeGB = [math]::Round($Stats.sum / 1GB ,2)
       
    $TempObject.NumberofMailboxes = $Stats.count
       
    $TempObject.AverageMailboxSizeMB = [math]::Round($Stats.average / 1MB,2)
       
    $TempObject.MaxMailboxSizeMB = [math]::Round($Stats.maximum / 1MB,2)
       
       
    #Add the TempObject to the Result Array for final output
        $ResultSet += $TempObject
    }

    #Compute Organizational Totals From Existing ResultSet

    #Create a copy of the Template
    $TempObject = $TemplateObject | Select-Object *

    $AllDBFilesizeGB = $ResultSet | Measure-Object DatabaseFileSizeGB -Sum
    $AllMailboxSizeGB = $ResultSet | Measure-Object TotalMailboxSizeGB -Sum
    $AllMailboxCount = $ResultSet | Measure-Object NumberofMailboxes -Sum
    $AllAverageMailboxSizeMB = $ResultSet | Measure-Object AverageMailboxSizeMB -Average
    $AllMaxMailboxSizeMB = $ResultSet | Measure-Object MaxMailboxSizeMB -Max

    #Save all this data we have into the template object
    $TempObject.DatabaseName = "All Databases (Pre-Exchange 2007 not included)"
    $TempObject.DatabaseFileSizeGB = $AllDBFilesizeGB.Sum
    $TempObject.TotalMailboxSizeGB = $AllMailboxSizeGB.Sum
    $TempObject.NumberofMailboxes = $AllMailboxCount.Sum
    $TempObject.AverageMailboxSizeMB = $AllAverageMailboxSizeMB.Average
    $TempObject.MaxMailboxSizeMB = $AllMaxMailboxSizeMB.Maximum

    #Add the TempObject to the Result Array for final output
    $ResultSet += $TempObject
        
    $ResultSet

    I hope this helps

    -Gary Siepser

     

    This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm.

Page 1 of 1 (2 items)