Tag Archives: Measure-Object

Minimum and Maximum Array Values

I determined something on Friday that I’m not sure I’ve needed before. I need to know which date in an array of dates, is the most recent—think the maximum value of the values in the array. Before we get to dates, let’s work with some simple-to-understand numeric values first.

In the below example, we’ll create a variable $Numbers and assign it five, out-of-order numerical values. Without much work, it’s easy to visually parse and determine the lowest value (the minimum value), and the highest value (the maximum value). One is the lowest and five is the highest.

$Numbers = 1,3,5,2,4
($Numbers | Measure-Object -Minimum).Minimum
1
($Numbers | Measure-Object -Maximum).Maximum
5

Let’s overwrite $Numbers with a different set of numbers—a larger set of random numbers. It’s not as easy to determine the smallest and largest of the numbers until we sort them.

$Numbers = Get-Random -Minimum 1 -Maximum 100 -Count 25
$Numbers
26
18
42
88
84
85
28
97
19
29
69
29
21
8
70
7
25
45
80
40
81
86
33
4
49
$Numbers | Sort-Object
4
7
8
18
19
21
25
26
28
29
29
33
40
42
45
49
69
70
80
81
84
85
86
88
97

Even though we can sort it, let’s return to Measure-Object and let it do the work for us. In the next two examples, you’ll notice that unlike the previous times I piped our array to Measure-Object, this time I didn’t only return the Minimum and Maximum properties. Instead, I returned all the properties in the object. They’re not all populated, but there’s a way to do that we’ll see soon enough.

$Numbers | Measure-Object -Minimum
Count             : 25
Average           :
Sum               :
Maximum           :
Minimum           : 4
StandardDeviation :
Property          :
$Numbers | Measure-Object -Maximum
Count             : 25
Average           :
Sum               :
Maximum           : 97
Minimum           :
StandardDeviation :
Property          :

Now, let’s try this with dates—both those that include times, and those that don’t. We’ll start by creating a $Date variable that contains five values. Once the values are assigned to our variable, we’ll display the contents of the array stored in our variable.

$Date = [datetime]'1/1/1975 02:05:48 PM',
[datetime]'2/2,1940',
[datetime]'1/1/1975 02:05:48 AM',
[datetime]'3/1/2022',
[datetime]'5/5/2080'
$Date
Wednesday, January 1, 1975 2:05:48 PM
Friday, February 2, 1940 12:00:00 AM
Wednesday, January 1, 1975 2:05:48 AM
Tuesday, March 1, 2022 12:00:00 AM
Sunday, May 5, 2080 12:00:00 AM

Let’s discuss the above dates before we move forward. We have one in 1940—the oldest—and one in 2080—the newest. These are the minimum and maximum, respectively. We have two on the same date in 1975. One happens at 2:05 in the morning and one at 2:05 in the afternoon. Which is the minimum and maximum of those values? You ought to be able to figure it out based on what you now know. Let’s work through some of the previous examples we did with our numerical array with this array. First, however, let’s ensure we’re working with an array—might as well.

$Date.GetType().BaseType.Name
Array

Ta-da. We’ll start by returning the minimum value, and then the maximum.

($Date | Measure-Object -Minimum).Minimum
Friday, February 2, 1940 12:00:00 AM
($Date | Measure-Object -Maximum).Maximum
Sunday, May 5, 2080 12:00:00 AM

Sure enough, 1940 is our minimum, and 2080 is our maximum. What happens when we sort the entire array? Will the two identical dates that include times sort properly? Let’s find out.

$Date | Sort-Object
Friday, February 2, 1940 12:00:00 AM
Wednesday, January 1, 1975 2:05:48 AM
Wednesday, January 1, 1975 2:05:48 PM
Tuesday, March 1, 2022 12:00:00 AM
Sunday, May 5, 2080 12:00:00 AM

They do. Now to put this to use! Perhaps I’ll be back with why I needed this. Before we wrap up though, let’s determine how to return more than just one property value at a time when using Measure-Object. Before that even, what happens when we don’t include any parameters?

$Numbers | Measure-Object
Count             : 25
Average           :
Sum               :
Maximum           :
Minimum           :
StandardDeviation :
Property          :

It only returns the Count property. We can use the AllStats parameter to return (just about) all of the properties at once.

$Numbers | Measure-Object -AllStats
Count             : 25
Average           : 46.52
Sum               : 1163
Maximum           : 97
Minimum           : 4
StandardDeviation : 29.7561198187308
Property          :

Until next time!

about_Aliases

This post is the help rewrite for about_Aliases. While the help files for Windows PowerShell are invaluable, the idea behind a rewrite is so true beginners might even better understand the help file concepts. At times, some things discussed in the Windows PowerShell help file will not be included in a help rewrite. Therefore, it is always best to read the actual help file after reading this post. (PS3.0)

An Alias in Windows PowerShell is a simplified, or quicker, way to type a cmdlet using an alternate name. Get-Alias (or the alias for Get-Alias, gal) will display a list of all of the aliases that the Windows PowerShell session knows about. This includes both built-in aliases and any additional aliases created or imported. The first two examples below, indicate two ways to accomplish the same thing–listing all the aliases. These examples only show the first four results.

PS C:\> Get-Alias

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           % -> ForEach-Object
Alias           ? -> Where-Object
Alias           ac -> Add-Content
Alias           asnp -> Add-PSSnapin

This example uses the alias for the Get-Alias cmdlet, gal.

PS C:\> gal

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           % -> ForEach-Object
Alias           ? -> Where-Object
Alias           ac -> Add-Content
Alias           asnp -> Add-PSSnapin

To find the cmdlet associated with a single alias, the alias needs to be provided, as the value for the -Name parameter, to the Get-Alias cmdlet.

PS C:\> gal -Name gc

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           gc -> Get-Content

The name parameter (-Name) is not required to use it. This means that if there is something after the Get-Alias cmdlet, such as gc in this example, then it will default to using the -Name parameter.

PS C:\> gal gc

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           gc -> Get-Content

Windows PowerShell will error if the -Name parameter is supplied with a cmdlet name or another value that is not an alias.

PS C:\> gal Get-Content

gal : This command cannot find a matching alias because an alias with the name ‘Get-Content’ does not exist.
At line:1 char:1
+ gal Get-Content
+ ~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (Get-Content:String) [Get-Alias], ItemNotFoundException
+ FullyQualifiedErrorId : ItemNotFoundException,Microsoft.PowerShell.Commands.GetAliasCommand

In order to get an alias (or aliases, if there is more than one) for a cmdlet, the -Definition parameter must be used.

PS C:\> gal -Definition Get-Content

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           cat -> Get-Content
Alias           gc -> Get-Content
Alias           type -> Get-Content

The Get-Service cmdlet returns the computer’s services, the Get-Process cmdlet returns the processes running on the computer, and the Get-ChildItem cmdlet returns the directories and/or files from the root of a drive or from a folder. Here is how a user can get the aliases for multiple cmdlets at the same time.

PS C:\> gal -Definition Get-Service,Get-Process,Get-ChildItem

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           gsv -> Get-Service
Alias           gps -> Get-Process
Alias           ps -> Get-Process
Alias           dir -> Get-ChildItem
Alias           gci -> Get-ChildItem
Alias           ls -> Get-ChildItem

There are a few other cmdlets that allow a user to work with aliases. By using the Get-Command cmdlet (or its alias–if it has one), additional cmdlets can be returned that all end with -Alias.

PS C:\> Get-Command *-Alias

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Export-Alias                                       Microsoft.PowerShell.Utility
Cmdlet          Get-Alias                                          Microsoft.PowerShell.Utility
Cmdlet          Import-Alias                                       Microsoft.PowerShell.Utility
Cmdlet          New-Alias                                          Microsoft.PowerShell.Utility
Cmdlet          Set-Alias                                          Microsoft.PowerShell.Utility

Export-Alias: Exports information about currently defined aliases to a file.

PS C:\> Export-Alias -Path 'C:\aliases.txt'

Import-Alias: Imports an alias, or aliases, from a file.

PS C:\> Import-Alias -Path 'C:\ImportedAliases.txt'

Trying to import aliases that already exist will cause an error for every alias Windows PowerShell tries to import (that already exists).

PS C:\> Export-Alias -Path 'C:\aliases.txt'
PS C:\> Import-Alias -Path 'C:\aliases.txt'
Import-Alias : The alias is not allowed, because an alias with the name ‘ac’ already exists.
At line:1 char:1
+ Import-Alias -Path ‘C:\aliases.txt’
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceExists: (ac:String) [Import-Alias], SessionStateException
    + FullyQualifiedErrorId : AliasAlreadyExists,Microsoft.PowerShell.Commands.ImportAliasCommand

New-Alias: Creates a new alias.
Set-Alias: Changes an existing alias, or creates an alias if it does not already exist.

PS C:\> New-Alias -Name MyAlias -Value Get-Process
PS C:\> MyAlias | select -First 4

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    224      19     3440        772   110    16.50   4612 ALMon
    164      14     2476       2108    44     5.36   2744 ALsvc
     77       9     1336       5288    75   137.55   4076 ApMsgFwd
     90       8     1372       5788    76   162.11   4324 ApntEx

PS C:\> Set-Alias -Name MyAlias -Value Get-Service
PS C:\> MyAlias | select -First 4

Status   Name               DisplayName
------   ----               -----------
Running  AdobeARMservice    Adobe Acrobat Update Service
Stopped  AdobeFlashPlaye... Adobe Flash Player Update Service
Stopped  AeLookupSvc        Application Experience
Stopped  ALG                Application Layer Gateway Service

Bonus Information

Use the Measure-Object cmdlet, or the count property, to find out how many aliases Windows PowerShell knows about.

PS C:\> Get-Alias | Measure-Object

Count    : 182
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

PS C:\> gal | measure

Count    : 182
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

PS C:\> (gal | measure).count
182
PS C:\> (gal).count
182

Real World

While aliases are helpful in the console, the belief is that they should not be used in a script file (.ps1 file). Using full cmdlet names in a script is preferred for script readability. There are plenty of people writing Windows PowerShell who adhere to this best practice even while using aliases for the object cmdlets (select for Select-Object, where for Where-Object, etc.).

Learn More

This information, and more, are stored in the help file about_Aliases that comes with Windows PowerShell. This information can be read by typing any of the commands below. The first example will display the help file in the Windows PowerShell console, the second example will open the full help in its own window, and the third example will send the contents of the help file to the clipboard (so it can be pasted into Word, Notepad, etc.), and the fourth example will open the help file in Notepad.

PS C:\> Get-Help about_aliases
PS C:\> Get-Help about_aliases -ShowWindow
PS C:\> Get-Help about_aliases | clip
PS C:\> Notepad C:\Windows\System32\WindowsPowerShell\v1.0\en-US\about_Aliases.help.txt

There is a built-in, automatic variable $PSHOMEthat stores the installation path of Windows PowerShell. This means that the third example above could have been partially written using that variable.

PS C:\> Notepad $PSHOME\en-us\about_Aliases.help.txt