get-service | where {$_.name -match "win"}

Normally displays like this:
Powershell_ouptut_normal

Note how very long names can get cut off with the ellipses….

Did you know that Powershell has a “grid-view”, similar to SQL?

get-service | where {$_.name -match "win"} | out-gridview

Powershell_output_gridview

If you pipe all get-service to the out-gridview, then you can see how you can even filter the data using the “GUI” mode.
Click “Add Crtieria”, then click the checkbox next the desired property name.
Powershell_output_gridview_AddCriteria

 

You can then enter a match/contains value for that property, and the grid instantly changes to show only the matching data:

Powershell_output_gridview_NameContains

Instead of filtering with the “contains” clause, you can click the word “contains”, and choose other methods of filtering.

I was truly amazed when I discovered this feature.

Powershell_output_gridview_Filter_Options

 

This is basically a follow-up to the previous post How to add a where filter match/contains/like to any powershell cmdlet (such as Get-Service)

Cmdlets are named in the format “verb-noun”, for example get-service, start-service, etc…
Suppose you cannot remember all the verbs associated with a noun. You can run this:

get-command -Noun process

Powershell_output_getcommand_Noun_Process

Recall from the prior blog you can do something like this to get all your BizTalk Host Instances (services):

get-service  | where {$_.name -match "biztalk"}

Now, suppose you wanted to start all the BizTalk Host Instances, you just pipe the results of the previous command to the “start-service” cmdlet. (Note: You may have to run Powershell “as admin” to avoid any security errors.)

get-service  | where {$_.name -match "biztalk"} | start-service 

There is an interesting optional parm that let’s you check your script. The “-WhatIf” parm can be added to Start-Service or Stop-Service. It will then only shows what would happen if the cmdlet runs. The cmdlet is not run.

Example:

PS C:\WINDOWS\system32> get-service | where {$_.name -match "DTC"} | stop-service -whatif
What if: Performing the operation "Stop-Service" on target "Distributed Transaction Coordinator (MSDTC)".

If you check the status of the service after running the above stop-service, you will see that it didn’t really stop.

Sometimes, when property names contain very long values, the default displays cuts part of the name, as shown with this command and its output.

[“ellipsis” is the term for the … when a name is truncated] as shown in the example below:

get-service | where {$_.name -match "win"}  | sort-object Status -desc

 

Powershell_ouptut_normal_with_ellipses

Red box is only added to bring your attention to the …

Simply pipe the result to the “ft -auto” cmdlet.

get-service | where {$_.name -match "win"}  | sort-object Status -desc | ft -auto
Powershell_ouptut_ft_auto

The full name is now displayed

ft is just the abbreviation for format-table, so you could have typed:

get-service | where {$_.name -match "win"}  | sort-object Status -desc | format-table -auto

Or as was discussed in my previous blog, you can use the grid view:

get-service | where {$_.name -match “win”} | out-gridview

Powershell_output_gridview

get-process  |  {$_.name -match "win"}

Sample output is shown below. The above means “get all the process objects on this computer” and pipe that collection of objects to a where/filter where we only want to see processNames that contain the letters “host”.

Example output:

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     75       8      796       3680    46             744 wininit
    152       8     1548       8072    54             776 winlogon

“Match” actually does a RegEx (regular expression match, so you can also do this: Find me all process that contain a “t” followed by exactly three characters, followed by the letters “host”:

PS C:\Users\Neal> get-process  | where {$_.name -match "t\w{3}host"}

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    181      17     9696      10796   693            7212 taskhost
    290      51    10992      17588   301     0.33   2860 taskhostex

How does this relate to BizTalk? We often deal with windows services. Suppose you are wondering if there is a DTC task started on the computer, but you don’t remember the exact service name.
Run something like this:

get-service | where {$_.name -match "dtc"}

Of course, if you remember the exact service name, you can enter a shorter command:

get-service -Name msdtc

On my home PC, both the above return the same result:

Status   Name               DisplayName
------   ----               -----------
Stopped  MSDTC              Distributed Transaction Coordinator

Suppose you wanted to show all processes that are stopped:

get-service | where {$_.Status -eq 'Stopped'}

Or show me only services that contain the “dtc” in the name that are stopped:

get-service | where {$_.Status -eq 'Stopped' -and $_.Name -match 'dtc'}

TIPS: Don’t forget to use -EQ instead of the = or == sign. This is not C#. Also don’t forget to put the – in front of -and, -eq, and -match.

To know what properties you can query with the -eq and the -match filter, do the following:

get-service | get-member

or the abbreviation for get-member “gm” is often used

get-service | gm

In this case, you are piping the output of the “get-service” cmdlet to the “get-member” cmdlet, which displays returns all the property, methods, and events.

Powershell_ouput_get-service-gm

Just to complete the thought, you can see just the properties by doing either of the following:

get-service | get-member  | where-object  {$_.MemberType -eq "Property"}

get-service | get-member -MemberType Properties

Powershell_ouput_get-service-gm_PropertiesOnly

Just for the sake of completeness, you might also want to sort your data by some particular property. Just pipe what we learned above to the “sort-object” and tell it which property (and optionally which order) to sort.

get-service | where {$_.name -match "dtc"} | sort-object Status
get-service | where {$_.name -match "dtc"} | sort-object Status -desc 

The purpose of this script is to monitor disk space on a list of servers. Right now, it uses a hard-coded 20% as the point at which to send the email (look for variable $thresholdspace in the code below). An enhancement could be to have different percents on each server. The script reads a file that has a list of servers to be monitored; it will check each disk on each of those servers.

BizTalk and other server level products can come to a screeching halt if there is not enough disk space on the servers.

#########################################################
#
# Disk space monitoring and reporting script
# Neal Walters - 06/18/2013 - found original code on web 
#                             then customized 
#
#########################################################
 
[string[]] $users = "test@abc.com","test2@abc.com","admin@xyz.com" # List of users to email your report to (separate by comma) or use a distribution list 
$fromemail = "FromEmail@abc.com"
$server = "your.emailRelayServer.com" #enter your own SMTP or Relay server DNS name / IP address here

$list = $args[0] #This accepts the argument you add to your scheduled task for the list of servers. i.e. list.txt
$computers = get-content $list #grab the names of the servers/computers to check from the list.txt file.
# Set free disk space threshold below in percent (default at 10%)
[decimal]$thresholdspace = 20
 
#assemble together all of the free disk space data from the list of servers and only include it if the percentage free is below the threshold we set above.
$tableFragment= Get-WMIObject  -ComputerName $computers Win32_LogicalDisk `
| select __SERVER, DriveType, VolumeName, Name, @{n='Size (Gb)' ;e={"{0:n2}" -f ($_.size/1gb)}},@{n='FreeSpace (Gb)';e={"{0:n2}" -f ($_.freespace/1gb)}}, @{n='PercentFree';e={"{0:n2}" -f ($_.freespace/$_.size*100)}} `
| Where-Object {$_.DriveType -eq 3 -and [decimal]$_.PercentFree -lt [decimal]$thresholdspace} `
| ConvertTo-HTML -fragment
 
# assemble the HTML for our body of the email report.
$HTMLmessage = @"
<font color=""black"" face=""Arial, Verdana"" size=""3"">
<u><b>Disk Space Storage Report</b></u>
<br>This report was generated because the drive(s) listed below have less than $thresholdspace % free space. Drives above this threshold will not be listed.
<br>
<style type=""text/css"">body{font: .8em ""Lucida Grande"", Tahoma, Arial, Helvetica, sans-serif;}
ol{margin:0;padding: 0 1.5em;}
table{color:#FFF;background:#C00;border-collapse:collapse;width:647px;border:5px solid #900;}
thead{}
thead th{padding:1em 1em .5em;border-bottom:1px dotted #FFF;font-size:120%;text-align:left;}
thead tr{}
td{padding:.5em 1em;}
tfoot{}
tfoot td{padding-bottom:1.5em;}
tfoot tr{}
#middle{background-color:#900;}
</style>
<body BGCOLOR=""white"">
$tableFragment
</body>
"@
 
# Set up a regex search and match to look for any <td> tags in our body. These would only be present if the script above found disks below the threshold of free space.
# We use this regex matching method to determine whether or not we should send the email and report.
$regexsubject = $HTMLmessage
$regex = [regex] '(?im)<td>'
 
# if there was any row at all, send the email
if ($regex.IsMatch($regexsubject)) {
                        send-mailmessage -from $fromemail -to $users -subject "Disk Space Monitoring Report" -BodyAsHTML -body $HTMLmessage -priority High -smtpServer $server
						Write-Host "Email sent" 
}
 
# End of Script

Then create a wrapper .bat or .cmd file like this:

powershell -command "& 'I:\Scripts\DiskMonitor.ps1'" DiskMonitorComputerList.txt

Then you create a file called DiskMonitorComputerList.txt that contains a list of servers:

ServerName1
ServerName2
MachineName3

Maybe a VP at works ask you “What is BizTalk”?  Can you give him a quick answer?

As a Dallas BizTalk Consultant, do you have a hard time explaining what you do for a living to your family and friends?
Maybe this video will help.  Using the Parker Brothers game called “Watersworks Leaky Pipe Card Game” we can make up some illustrations to make the complexities more simple.