Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Wednesday, February 27, 2013

Displaying information on the host with PowerShell

PowerShell scripters have a variety of methods that they can use to display information on the host.  Before we begin this lesson, remember that PowerShell should send an object as it’s output to the PowerShell pipeline.  In many cases, the author of a cmdlet may want to display other information.  This can include debugging or progress information.  Here are a few cmdlets and some information to help you understand their usage.

Write-Output

This is the proper way of sending output into the PowerShell pipeline.  Remember that this should be the object that is the end result of the code that was just executed.  This is also how we return information from a function to its calling statement.

Write-Host

This is the easiest cmdlet to use to instantly display information on the host.  The –ForeGroundColor and –BackGroundColor parameters allow you to use 16 different colors to emphasis your displaying information. 

Example:

PS C:\> Write-Host "Hello World" -ForegroundColor Red -BackgroundColor DarkYellow

Hello World

Write-Debug

This cmdlet is dependent on the setting of the environmental variable $DebugPreference. By default, it is set to SilentlyContinue.  By setting this variable to Continue, you will be able to write debug information to the host.  The advantage of this cmdlet is that it does not display information by default.  That means you can leave your debug comments in your script for later use and the user will not see them when the cmdlet is executed unless the user sets their $DebugPreference$ to continue.

Write-Host "Here is some code"

$Debugpreference = 'Continue'

Write-Debug "Here is the debug information"

$Debugpreference = 'SilentlyContinue'

Write-Debug "This debug message will not display."

Write-Host "End of Script"

 

Here is some code

DEBUG: Here is the debug information

End of Script

You can see that once the $DebugPreference variable was set to SilentlyContinue, the second debug message is not displayed.

One of the common parameters is –Debug.  By using this common parameter, you can turn on debug messages.  This switch will override the value of $DebugPreference value.  The difference is that it will pause script execution at each debug message.  Since the script is still running in memory, you can examine the contents of memory by placing the script in Suspend mode.

Function Test

{

[cmdletbinding()]

Param()

Write-Host "Here is some code"

Write-Debug "Here is the debug information"

Write-Debug "This debug message will not display."

Write-Host "End of Script"

}

image

Write-Verbose

This write cmdlet is controlled by the $VerbosePreference environmental variable.  It is also set to SilentlyContinue.  This one is actually a common parameter.  Talk a look at the help file About_CommonParameters to learn more.   This means that you can use the –Verbose switch with your cmdlet to see this information.  This cmdlet is best used to provide progress information for the cmdlets execution.

Function Test

{

[cmdletbinding()]

Param ([Switch]$PassThru)

 

Write-host "Hello"

Write-Verbose "World"

}

 

PS C:\> Test

Hello

 

PS C:\> Test -Verbose

Hello

VERBOSE: World

 

 

Write-Warning

This cmdlet can be used to write a warning to the host.  It is controlled by the $WarningPreference variable.  It is set to Continue by default.

PS C:\> Write-Warning "This is a Warning Meassage"

WARNING: This is a Warning Meassage

 

PS C:\> $Var1 = "This is also a message"

 

PS C:\> $Var2 = "And so is this one."

 

PS C:\> $Var1, $Var2 | Write-Warning

WARNING: This is also a message

WARNING: And so is this one.

 

Write-Error

Write-Error is a bit more complex to use.  The detailed help file for this cmdlet provides more detailed information on how to use this cmdlet.  Write-Error places an object into the Error stream.  Look at this example.

 

PS C:\> Write-error "Hello"

Write-error "Hello" : Hello

    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException

    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

It is not as pretty to look at.  It does place this information into the $Error array.

PS C:\> $Error[0]

Write-error "Hello" : Hello

    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException

    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

Before using this cmdlet, take come time to study the help file on it so you can use it properly.

To get a list of all write cmdlets:

PS C:\> Get-Command write*

 

CommandType Name                  ModuleName                    

----------- ----                  ----------                    

Alias       write -> Write-Output                               

Function    Write-Quantification  PSv3                          

Cmdlet      Write-Debug           Microsoft.PowerShell.Utility  

Cmdlet      Write-Error           Microsoft.PowerShell.Utility  

Cmdlet      Write-EventLog        Microsoft.PowerShell.Management

Cmdlet      Write-Host            Microsoft.PowerShell.Utility  

Cmdlet      Write-Output          Microsoft.PowerShell.Utility  

Cmdlet      Write-Progress        Microsoft.PowerShell.Utility  

Cmdlet      Write-Verbose         Microsoft.PowerShell.Utility  

Cmdlet      Write-Warning         Microsoft.PowerShell.Utility  

Application write.exe                                           

Application write.exe                   

                          

To get a list of the variable that control the output of several of these cmdlets:

 

PS C:\> Get-Variable *Preference

 

Name                  Value          

----                  -----          

ConfirmPreference     High           

DebugPreference       SilentlyContinue

ErrorActionPreference Continue       

ProgressPreference    Continue       

VerbosePreference     SilentlyContinue

WarningPreference     Continue       

WhatIfPreference      False 

 

 

Monday, February 25, 2013

How to list all members of a Distribution group and their emails with PowerShell

This question came from the need of a user who needed to extract the following information:

Distribution Group Name | Group Email | Group Member | Member’s Email

 

Function Get-DistributionEmail

{

 

    # Get a list of all the distribution groups in the domain.

    $Groups = Get-ADGroup -Filter 'GroupCategory -eq "Distribution"' -Properties Mail

 

    # Create a dynamic array to hold the objects for the output.

    $Obj = @()

   

    # Loop through each group.

    ForEach ($Group in $Groups)

    {

        # Enumerate all the members of the group.

        $Members = Get-ADGroupMember -Identity $Group.name

       

        # Collect the data for the output.

        ForEach ($Member in $Members)

        {

            $GroupObj = New-Object PSObject

            $GroupObj | Add-Member `

             -MemberType NoteProperty `

             -Name "Group" `

             -Value $Group.Name

           

            $GroupObj | Add-Member `

             -MemberType NoteProperty `

             -Name "GroupEmail" `

             -Value $Group.Mail

 

            $GroupObj | Add-Member `

             -MemberType NoteProperty `

             -Name "User" `

             -Value $Member.Name

           

            $User = get-ADuser -filter 'Name -eq $Member.name' -Properties Mail

 

            $GroupObj | Add-Member `

             -MemberType NoteProperty `

             -Name "UserEmail" `

             -Value $User.Mail

 

             # Transfer the object to the dynamic array.

             $Obj += $GroupObj

        }

    }

    # Wrtie the contents of the array to the PowerShell pipeline.

    Write-Output $Obj | FT -AutoSize

<#

.SYNOPSIS

Gather all user accounts and email addresses of Distribution Group members.

 

.DESCRIPTION

Gather all user accounts and email addresses of Distribution Group members.

 

.EXAMPLE

Get-DistributionEmail

 

Group  GroupEmail      User  UserEmail    

-----  ----------      ----  ---------    

Group1 Group1@Indy.com User1 User1@Indy.com

Group1 Group1@Indy.com User2 User2@Indy.com

Group2 Group2@indy.com User3 User3@indy.com

Group2 Group2@indy.com User4 User4@indy.com

 

.NOTES

Requires the Active Directory module to be available.

#>

}

Wednesday, February 20, 2013

List all the scripts my GPOs run.

This is an interesting question that I picked up from my moderator duties on PowerShell.com.  The question was how do I know what scripts are being run by my GPOs?  The function below will enumerate all of your GPOs and then let you know what scripts are being run.

 

 

 

Function Get-GPOScripts

{

    $GPOS = Get-GPO -all

    ForEach ($GPO in $GPOs)

    {

   

        $Obj = New-Object -TypeName PSOBject

        $Obj | Add-Member -MemberType NoteProperty -Name "GPO" -Value $GPO.Displayname

 

        [xml]$xml = Get-GPOReport -Name $GPO.DisplayName -ReportType xml

 

        $User = $xml.documentelement.user.extensiondata.extension.script.command

        $computer = $xml.documentelement.Computer.extensiondata.extension.script.command

 

        $Incriment = 1

        $UserScript = @()

        ForEach ($U in $User)

        {

            $US = New-Object -TypeName PSObject

            $Script = ($U.Split("\"))[-1]

            $US | Add-Member -MemberType NoteProperty -Name "Script" -Value $Script

            $UserScript += $US

        }

 

        $ComputerScript = @()

        ForEach ($C in $Computer)

        {

            $CS = New-Object -TypeName PSObject

            $Script = ($C.Split("\"))[-1]

            $CS | Add-Member -MemberType NoteProperty -Name "Script" -Value $Script

            $ComputerScript += $CS

        }

        $Obj | Add-Member -MemberType NoteProperty -Name "UserScript" -Value $UserScript

        $Obj | Add-Member -MemberType NoteProperty -Name "ComputerScript" -Value $ComputerScript

 

 

        Write-Output $Obj

    }

}

 

Run it like this:

image

 

Since this function outputs an object, we can continue using it in the PowerShell Pipeline if we want to.  In this case, we see that GPO Demo1 has some scripts.

 

image

To list them:

image