Advanced Windows PowerShell Scripting Video Training

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

Wednesday, October 31, 2012

Export Your Performance Monitor Data to Excel

Updated: 2016MAY04

To clarify when this functionality is available, you can only save the view when you are viewing a Data Collection Set.  The "live" data cannot be saved in this way.

Performance Monitor in Windows Server give us the ability to see when our servers are having some issues.  Analyzing that data into something meaningful can be a problem.  You can export your data to Excel so you can better see what your performance data represents. 
First collect your data.
image
Right click the graph and select Save Data As.
Change the Save as type to Text file (comma delimited)(*.csv).
Give the file a name and save it where you want to store it.
Now open that file on a client with Excel installed on it.  By using excel, you will be able to present the data in a more meaningful format.

Monday, October 29, 2012

How to write a string of text in multiple colors in PowerShell

One of the features about PowerShell that drew my attention away from VBScript many years ago was PowerShell’s ability to output information in multiple colors.  When you use Write-Host to display text on the screen, you also get to use the ForegroundColor and BackgroundColor parameters to change the font colors for that line of text.

What if you wanted to have a line of text with different colors?  To do this you will need to to use several Write-Host lines.  The problem with that is that you will have your text on multiple lines.  In the Help file for Write-Host, I noticed a parameter NoNewLine that will not put a return at the end of the text.  Your next Write-Host statement will appear on the same line.  Take a look at the code below and the output.

Write-host "This is some" -ForegroundColor Green -NoNewline
Write-Host "string" -ForegroundColor Red -BackgroundColor DarkRed -NoNewline
Write-Host "in different" -ForegroundColor Gray -BackgroundColor DarkYellow -NoNewline
Write-Host "Colors"

image

Wednesday, October 24, 2012

Use Performance Monitor to Help You Discover Performance Counters for PowerShell

More often than not in my PowerShell classes, I get asked questions about collecting performance information using PowerShell.  One of the big issues that my clients have is how to discover the correct syntax for the performance counters that they want.  The answer is simple, just look at Performance Monitor.
We could use the cmdlet Get-Counter –Listset *, but that returns way to much information. Open Performance Monitor and create a Data Collection Set.  (You can find instructions on how to set up a Data Collection Set here.)
Collect one sampling of your data and display it in Performance Monitors graph.
Right click the graph and select Save Data As.
Change the Save as type to Text file (comma delimited)(*.csv).
Give the file a name and save it where you want to store it.
Now open that file on a client with Excel installed on it.
Take a look at the column headers.  They are the counter data that you want to use in PowerShell.
image
image
Notice that you can remove the client name so the cmdlet only targets the server it is running on.
image





Monday, October 22, 2012

Get the name of a Server using the SID

In class we received audit logs that contained only a SID.  Since we were interested in getting the name of the client associated with that SID, we turned to PowerShell for the answer.

The SID actually contains two parts.  A unique code for the domain and then the Relative Identifier (RID) for the the client. This RID is the last portion of the SID and is unique in the network.  Below is an example.

S-1-5-21-3400766600-4132462866-2336755051-1149

The RID is the numbers 1149.  This is what we need to search for in Active Directory.  For a client, use this PowerShell command.

Get-ADComputer –Filter * –Properties | Where-Object {$_.SID –like “*1149”} | Select-Object –Property Name, SID

image

The Get-ADComputer cmdlet will retrieve all computer objects in Active Directory. The –Properties parameter will add the SID to the default set of attributes that are returned from the Get-ADComputer cmdlet.

The Where-Object cmdlet will filter all the computer objects for one with a SID that ends in 1149.

The Select-Object cmdlet will remove all attributes from the output except the name and the SID.

Thursday, October 18, 2012

North America MCT Summit Day 1

Day one here in Redmond was a lot of fun.  Microsoft Learning briefed us on what is to come and showed us new services and resources that we can use to provide a higher level of service to our clients.  I tagged a few to try out myself.  I also had the opportunity to take 4 MTA exams and provide feedback on them.  I’m happy to say I passed them all. I also got my first look at the 20417 MCAS upgrade exam. It is not one to take lightly.

I want to thank June Blender for giving me the opportunity to participate in her session on PowerShell 3.0.  I’m always happy to help. 

Now that I finally got some sleep, I’m ready to tackle Day 2.

Wednesday, October 17, 2012

Automatically create a log of your PowerShell sessions

In my October 3rd article, I wrote about using the PowerShell transcript feature to create a log file of everything you do.  This is a good idea, but it is a manual task.  Here is how you make it automatic.  We are going to use your PowerShell profile.  If you have not yet created a profile, take a look at my blog entry on September 24, 2012.

First, create a location to store your transcripts.  This file will contain a lot so it is best to get it organized now. My file is in My Documents in the PowerShell\Transcript folder.  You put yours where it makes sense to you.

Now, open your profile.  In PowerShell, type PowerShell_ise $Profile.

Enter this set of code in your profile.

# -- Automate PowerShell Transcription --
#
Create a filename based on a time stamp.
$Filename = ((Get-date).Month).ToString()+"-"+`
((
Get-date).Day).ToString()+"-"+`
((
Get-date).Year).ToString()+"-"+`
((
Get-date).Hour).ToString()+"-"+`
((
Get-date).Minute).ToString()+"-"+`
((
Get-date).Second).ToString()+".txt"
# Set the storage path.
$Path = "C:\Users\Jason\Documents\PowerShell\Transcript"
# Turn on PowerShell transcripting.
Start-Transcript -Path "$Path\$Filename"
# ---------------------------------------

This will start the transaction functionality every time you start the PowerShell environment, and put it in the folder specified in the –Path parameter.  Now save your profile.  Close the shell and reopen it.


Your session will start similar to this:


Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. All rights reserved.


Transcript started, output file is C:\Users\Jason\Documents\PowerShell\Transcript\8-12-2012-19-32-48.txt
PS C:\Users\Jason>


Take a look in your designated log location, you now have transcripts starting automatically for each session.


image

Monday, October 15, 2012

How to run GPResult on a remote client with PowerShell

In the past, to run the GPResult command, you would need to either physically visit this client, have the user do it, or use and RDP connection.  In all cases, this will disrupt the user.  First, you need PowerShell remoting enabled on the target machine.  You can do this via Group Policy.

Open PowerShell and type this command.

Invoke-Command –ScriptBlock {GPResult /r} –ComputerName <ComputerName>

Replace <ComputerName> with the name of the target.  Remember, the target needs to be online and accessible to you.

Friday, October 12, 2012

Forcing a remote GPUpdate on a Client

Many times I have had to talk a remote user through a manual refresh of Group Policy.  Depending on the comfort level of the user, this is either a comfortable processes or a highly stressful event…for both of us.  You can use PowerShell V3 to invoke a GPUpdate on a remote client.  You need to get a few items in order first.

 

1 – Access to the GroupPolicy module. 

Your domain controllers have access to the GroupPolicy module. This is installed by default when they became domain controllers  For Windows 8 clients, download RSAT from here.

Once you have access to the module, you need to turn it on. Click Start and Type Programs and Features.

If you are using Windows 8, you will also need to click Settings.

image

Click Programs and Features

Click Turn Windows Features on or off. This will take a few minutes.

Expand Remote Server Administration Tools / Feature Administration Tools.

Check Group Policy Management Tools.

image

Click OK.

2 – Configure the Firewall to allow Group Policy Remote Updates.

For Server 2008 R2, you need to manually open the following ports for inbound traffic on your clients.

  • TCP RPC dynamic ports, Schedule (Task Scheduler service)
  • TCP port 135, RPCSS (Remote Procedure Call service)
  • TCP all ports, Winmgmt (Windows Management Instrumentation service)

Windows Server 2012 has a Starter GPO to help you out with this.

Open Server Manager.

Click Tools and select Group Policy Management

Expand the Group Policy Management tree to expose your domain.

Click Starter GPOs.  If this is the first time you have used Starter GPOs, you will see this:

image

Click Create Starter GPOs Folder.

You will now see a list of the Starter GPOs.

image

Right click where you want to scope this GPO to and then click Create a GPO in this…..

image

In the New GPO name, type the name that you want.

In the Source Starter GPO drop down box, select Group Policy Remote Update Firewall Ports

Click OK.

You need to let this GPO replicate to your clients before you can invoke a remote GPUpdate.

To test you remote update, log onto a client that you will force the remote update on.

Open PowerShell

Type GPResult /r and press Enter

Take note of the last time the the GPO was refreshed on either the Computer or User section.

image

Before proceeding, make sure that you are not attempting to do a remote update on clients in the default Computers container in active directory.  Move them to an Organizational Unit first.

Now, go to the server/client that you are going to invoke the remote GPUpdate from.

Open PowerShell. 

Type Invoke-GPUpdate –Computer <ComputerName> –Force –RandomDelay 0 and press Enter.  Replace <ComputerName> with the name of the remote client.

This will create a scheduled task on the remote client.  It will execute immediately with the –RandomDelay parameter set to 0.  The user will see a command window pop up as shown below. It will close automatically.

image

The remote update is now completed.

If you run a GPResult /r on the client, you will see that it has been updated.

image

Wednesday, October 10, 2012

Expanding Custom ErrorVariable usage in PowerShell

Using the PowerShell common parameter –ErrorVariable allows you to capture the error that a cmdlet has produced so you can work with it. Take a look at the following code:

$Computers = "NotOnline"

ForEach ($Computer in $Computers)

{

    Get-WmiObject Win32_OperatingSystem -ComputerName $Computers -ErrorVariable +MyErrors

    Get-Service -ComputerName $Computer -ErrorVariable +MyErrors

    Get-Content -Path c:\DoesNotExists.txt -ErrorVariable +MyErrors

}

If we look at the $MyError variable, we receive the same information that is displayed on the screen:

$MyErrors

Get-Content : Cannot find path 'C:\DoesNotExists.txt' because it does not exist.

At line:6 char:5

+     Get-Content -Path c:\DoesNotExists.txt -ErrorVariable MyErrors

+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (C:\DoesNotExists.txt:String) [Get-Content]

   , ItemNotFoundException

    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentComman

   d

What about when we use code like this in which we want to reuse the error variable?

$Computers = "NotOnline"

ForEach ($Computer in $Computers)

{

    Get-WmiObject Win32_OperatingSystem -ComputerName $Computers -ErrorVariable MyErrors

    Get-Service -ComputerName $Computer -ErrorVariable MyErrors

    Get-Content -Path c:\DoesNotExists.txt -ErrorVariable MyErrors

}

 

 

This is what is contained inside the $MyErrors variable:

$MyErrors

Get-Content : Cannot find path 'C:\DoesNotExists.txt' because it does not exist.

At line:6 char:5

+     Get-Content -Path c:\DoesNotExists.txt -ErrorVariable MyErrors

+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (C:\DoesNotExists.txt:String) [Get-Content]

   , ItemNotFoundException

    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentComman

   d

 

Only one error remains.

 

In other words, you would have to write code to take a look at each error and decide what to do then.  This may not be suitable for your code.  You could turn your custom error variable into an array. You can do this by adding the  +’ character in front of your custom variable.  See below:

 

$Computers = "NotOnline"

ForEach ($Computer in $Computers)

{

    Get-WmiObject Win32_OperatingSystem -ComputerName $Computers -ErrorVariable +MyErrors

    Get-Service -ComputerName $Computer -ErrorVariable +MyErrors

    Get-Content -Path c:\DoesNotExists.txt -ErrorVariable +MyErrors

}

 

 

Now here is the output of $MyErrors:

PS C:\Users\Jason> $MyErrors

Get-Content : Cannot find path 'C:\DoesNotExists.txt' because it does not exist.

At line:6 char:5

+     Get-Content -Path c:\DoesNotExists.txt -ErrorVariable MyErrors

+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (C:\DoesNotExists.txt:String) [Get-Content]

   , ItemNotFoundException

    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentComman

   d

 

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)

At line:4 char:5

+     Get-WmiObject Win32_OperatingSystem -ComputerName $Computers -ErrorVariable  ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException

    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObje

   ctCommand

 

Cannot open Service Control Manager on computer 'NotOnline'. This operation might require

other privileges.

Get-Content : Cannot find path 'C:\DoesNotExists.txt' because it does not exist.

At line:6 char:5

+     Get-Content -Path c:\DoesNotExists.txt -ErrorVariable +MyErrors

+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (C:\DoesNotExists.txt:String) [Get-Content]

   , ItemNotFoundException

    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentComman

   d

 

You can see that it contains all the errors. Your variable is now an array.  You can get the count information of how many cells are in the array.

$MyErrors.count

4

 

You can also access the array via index number.

$MyErrors[1]

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)

At line:4 char:5

+     Get-WmiObject Win32_OperatingSystem -ComputerName $Computers -ErrorVariable  ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException

    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObje

   ctCommand

 

The custom error variable will continue to append new data to it until you send data to it without the ‘+’ character.  For that reason, the first time you use it in your script, you may want to omit the ‘+’ character so you clear the array each time the script is ran in your current PowerShell session.

 

Monday, October 8, 2012

How to set a Server Side Autoreply with PowerShell

The question from class was how to set a mailbox to autoreply to the sender.  In this case, if the sender is requesting support, this auto response will let them know that their email has been received.  It turns out this is a simple one liner in PowerShell.
The below command is one continuous line.  This needs to be execute in the Exchange Management Console on the Exchange server.
Set-MailboxAutoReplyConfiguration –Identity ITHelpdesk –InternalMessage Thank you. Your message has been received. A member of the help desk will contact you shortly. –AutoReplyState Enabled



Below is how it appears in Outlook for the user who sent the request.

image

If you expect email from outside your organization, you can also set an external rule.
Set-MailboxAutoReplyConfiguration –Identity ITHelpdesk –InternalMessage Thank you. Your message has been received. A member of the help desk will contact you shortly. –ExternalMessage Thank you. Your message has been received. A member of the help desk will contact you shortly. –AutoReplyState Enabled

Friday, October 5, 2012

Search for key words in PowerShell help files

One of my students from a PowerShell class a few weeks back was wondering if he could search PowerShell help files for key words and have those words highlighted in the help file.  This week I decided to tackle this one and here are the results.
Below is a screen shot of the function Search-Help
image
Please take the time to read through the help file.  The code below is presented as a function that can be turned into a module and added to your PowerShell profile.
This code is provided as is and without warranty or support.

Function Search-Help
{
[CmdletBinding(HelpUri = 'http://get-help-jason-yoder.blogspot.com/2012/10/search-help.html')]

Param(
    # Parameter $Cmdlet
    # The name of the parameter that you want to get help on.
    [Parameter(Mandatory=$true)]$Cmdlet,

    # Parameter $Words
    # The name of the parameter that you want to get help on.   
    [Parameter(Mandatory=$true)][String[]]$Words,

    # Parameter $Detailed
    # Parse the detailed help file of the cmdlet.
    [Switch]$Detailed,

    # Parameter $Detailed
    # Parse the full help file of the cmdlet.
    [Switch]$Full,

    # Parameter $MoreHighlight
    # Changes the highlighted text to a different
    # color set to make the search items stand out
    # better.
    [Switch]$MoreHighlight,

    # Parameter $ExactMatch
    # Changes the default behavior of the algorithm to
    # look for an exact match as opposed to a match
    # containing the query.
    [Switch]$ExactMatch

)
  
    # Supporting Function Compare-Strings -------------------------------------
    # Send this function:
    # 1: The word to examine.
    # 2: The word you want to see if it is in the first.
    # * and ? are acceptable wild car characters.
    # This function will return $TRUE is the $TestString contains the pattern
    # from $TestWord.  This function is the default behavior of the cmdlet.
    Function Compare-Strings
    {
    Param(
        [String]$TestString,
        [String]$TestWord
    )

        # Set the Return flag data
        [Boolean] $MatchFound = $False

        # Break the $TestString into a Cahr array
        $CharArray = $TestString.ToCharArray()

        # Loop through the CharArray, adding one character to the
        # Search to see if it matches.

        # The sting that holds the value to be tested.
        $TestArray = $Null

        # Controls the inner While loop and adds characters to be tested.
        $Index = 0

        # Controls the outer while loop and determines which characters
        # from the left to start the comparison with.
        $OuterIndex = 0

        Do
        {
            $Index = $OuterIndex
            Do
            {
                # Add a character to the test string
                $TestArray += $CharArray[$Index]
                If($TestArray -like $TestWord)
                {
                    $MatchFound = $True
                }
           
                # Increment the control variable.
                $Index++
           
            } While ($Index -Lt $TestString.length)

            # Clear the TestArray
            $TestArray = $Null
           
            # Increment the control variable
            $OuterIndex++
       
        } While ($OuterIndex -lt $TestString.length)
       
        # Return the data to the calling command.
        Write-Output $MatchFound
    }
    # End Supporting Function Compare-Strings ---------------------------------

    # Supporting Function Compare-StringsExact --------------------------------
    # Send this function:
    # 1: The word to examine.
    # 2: The word you want to see if it is in the first.
    # This function will return TRUE only if there is an exact match. 
    Function Compare-StringsExact
    {
    Param(
        [String]$TestString,
        [String]$TestWord
    )
        # Set the Return flag data
        [Boolean] $MatchFound = $False
       
        If($TestString -eq $TestWord)
        {
            $MatchFound = $True
        }

        # Test to see if a match is made by removing any end punctuation.
        If($TestString -match "\w*")
        {
            If($Matches.Values -eq $TestWord)
            {
                $MatchFound = $True
            }
        }
       
        # Return the data to the calling command.
        Write-Output $MatchFound       

    }
    # End Supporting Function Compare-StringsExact ----------------------------

    # get the help file from PowerShell.
    If($Detailed)
        {$HelpData = (Get-Help $Cmdlet -Detailed) | Out-String -Stream}
    ElseIf($Full)
        {$HelpData = Get-Help $Cmdlet -Full | Out-String -Stream}
    Else
        {$HelpData = Get-Help $Cmdlet | Out-String -Stream}


    # Set a counter to keep track of how many matches are found.
    $MatchCounter = 0

    # Validate the phrase that was sent to remove
    # any solo "*" or "?".
    $SearchPhrase = @()
    $Wordss = $Words.split(",")
    $InvalidItems = @()
    Foreach ($Item in $Wordss)
    {
        If (($Item -ne "*") -and ($Item -ne "?") -and (($Item.ToCharArray())[0] -ne "*") -and (($Item.ToCharArray())[0] -ne "?"))
        {
            $SearchPhrase += $Item
        }
        Else
        {
            $InvalidItems += $Item
        }
    }
    
    # Cycle through each line of the help file.   
    Foreach ($Item in $HelpData)
    {

        # Split each line into its individual words.           
        $StringData = $Item.Split()
       
        # Cycle through every word in the current help file line.
        ForEach ($DataItem in $StringData)
        {
            # Set this flag to $True is a match is found.
            $Found = $False
           
            # Cycle through each searchword.
            foreach ($Item in $SearchPhrase)
            {
                # Use the correct function depending on if the $ExactMatch flag is set.
                If ($ExactMatch)
                {
                   $ReturnedMatch = Compare-StringsExact $DataItem $Item
                }
                Else {$ReturnedMatch = Compare-Strings $DataItem $Item}
           
                If ($ReturnedMatch){$Found = $True}
            }
          
                # If the $Found flag is set to $True, then display the word
                # in highlighted text.  If not, display the word using the
                # current color settings in the shell.
                If ($Found)
                {
                    If (-Not $MoreHighlight)
                    {
                        Write-Host "$DataItem" -ForegroundColor Magenta -BackgroundColor DarkBlue -NoNewline
                        Write-Host " " -NoNewline
                    }
                    Else
                    {
                        Write-Host "$DataItem" -ForegroundColor Green -BackgroundColor DarkGreen -NoNewline
                        Write-Host " " -NoNewline
                    }
                    # Incriment the $MatchCounter.
                    $MatchCounter++
                }
                Else
                {
                    Write-Host "$DataItem " -NoNewline
                }
           
        }
        # This adds a carriage return to the line to ensure the output resembles
        # the original help file as much as possible.
        Write-Host ""
    }

    # Write an extra line of data to the end of the help file to let the user
    # know if a match was found.
    Write-Host "-- Search Results: -------------------------------------------------------------"
    If ($MatchCounter -gt 0)
    {
        Write-Host "Your search returned " -NoNewline
        Write-Host "$MatchCounter" -ForegroundColor Green -BackgroundColor DarkBlue  -NoNewline
        Write-Host " matches."
        Write-Host "Items searched for:"
        foreach ($Item in $SearchPhrase)
        {
            Write-Host $Item -ForegroundColor Green -BackgroundColor DarkBlue
        }
        If($InvalidItems.count -gt 0)
        {
            Write-Host "Invalid search items removed from the query:"
            foreach ($Item in $InvalidItems)
            {
                Write-Host $Item -ForegroundColor Red -BackgroundColor DarkBLue
            }
        }
    }
    Else
    {
        Write-Host "No matches were found."
    }
<#
.SYNOPSIS
Searches PowerShell help files for specific words.

.DESCRIPTION
Searches through PowerShell help files for words and highlights those words in the actual help files. 
The default setting for this cmdlet is to search for the pattern specified in the WORDS parameter in each word of the help file.

.PARAMETER Cmdlet
The cmdlet or About file that you want to search for specific words.

.PARAMETER Words
Comma separated list of words that you want to search for.  The words can contain * and ? characters but cannot start with a * or ? character.

.PARAMETER Detailed
Searches the cmdlets detailed help file.

.PARAMETER Full
Searches the cmdlets full help file.

.PARAMETER MoreHighlight
Displays the queried words in a higher contrast color scheme which may make the output more readable to some users.

.PARAMETER ExactMatch
This will change the pattern recognition to an exact match (not case sensitive).  Wildcard characters are not accepted.

.EXAMPLE
Search-Help Get-Date -Words Date

Returns the standard help file for the cmdlet Get-Date and highlights all words that match or contains "Date".

.EXAMPLE
Search-Help Get-Process P*ess, more, t?pe -MoreHighlight

Returns the standard help file for the cmdlet Get-Date and highlights all words that match or contains "Date" as well as "P*ess" and "T?py"
The "*" character is a wild card character that allows for multiple characters to exists in its place.
The "?" character is a wild card character that allows for a single character to exists in its place.
The highlighted words will also be returned in greater contrast.

.EXAMPLE
Search-Help About_Comparison_Operators "-Match"

Returns the help file for About_Comparison_Operators with all words matching or contains "-Match" highlighted.

.EXAMPLE
Search-Help Get-Process -detailed Process

Returns the detailed help file for the cmdlet Get-Date and highlights all words that match or contains "Date".

.EXAMPLE
Search-Help Get-Process -Words Process -ExactMatch

Returns the standard help file for Get-Process with all words that exactly match "Process" highlighted.

.NOTES
This cmdlet sends customized output to the host one line at a time.  For this reason, standard object output for PowerShell is not utilized.

.LINK
Online Version: http://get-help-jason-yoder.blogspot.com/2012/10/search-help.html
Get-Help
#>
}