Line 10:
If you are already familiar with PowerShell, you should be aware that PowerShell is an object oriented language. Objects have properties and methods. In PowerShell you normally see selection of properties using the pipeline and the select-object cmdlet.
get-item c:\windows | Select-Object LastWriteTime
Results
LastWriteTime
-------------
6/30/2017 3:29:16 PM
What is happening here is the get-item cmdlet is sending an object to the pipeline that represents the Windows folder and we are then selecting to show only the LastWriteTime property from the object.
If we wanted to show just the value of the LastWriteTime property, we could use the -ExpandProperty option
get-item c:\windows | Select-Object -ExpandProperty LastWriteTime
Results
Friday, June 30, 2017 3:29:16 PM
There is another way to access the value of the property however using the . syntax that is common to .NET.
Frequently you will see something like this instead.
$folder = get-item c:\windows
$folder.LastWriteTime
Results
Friday, June 30, 2017 3:29:16 PM
In this case, the object that results from the get-item cmdlet is stored in a variable. We are then using the . syntax to get the value from the LastWriteTime property of the object stored in the $folder variable.
What I am doing here, ($_ | Select-String “_(.*)”).Matches.Groups[1].value, is the same thing, except that I am not storing the value in a variable first. I am using the () to indicate to PowerShell that the code inside the () should be executed first, then using the . syntax to look at the properties of the resulting object.
Keeping with the previous example
(get-item c:\windows).LastWriteTime
Results
Friday, June 30, 2017 3:29:16 PM
Inside the () get-item results in an object, we then use the . syntax to look at the properties of that object.
In the same way ($_ | Select-String “_(.*)”) results in a “MatchInfo” object
"aws1288_plumber@contso.com" | Select-String "_(.*)" | get-member
Results
TypeName: Microsoft.PowerShell.Commands.MatchInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
RelativePath Method string RelativePath(string directory)
ToString Method string ToString(), string ToString(string directory)
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property string Filename {get;}
IgnoreCase Property bool IgnoreCase {get;set;}
Line Property string Line {get;set;}
LineNumber Property int LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property string Path {get;set;}
Pattern Property string Pattern {get;set;}
The MatchInfo object has a property called Matches which contains RexEx Match objects
("aws1288_plumber@contso.com" | Select-String "_(.*)").Matches | get-member
Results
TypeName: System.Text.RegularExpressions.Match
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
NextMatch Method System.Text.RegularExpressions.Match NextMatch()
Result Method string Result(string replacement)
ToString Method string ToString()
Captures Property System.Text.RegularExpressions.CaptureCollection Captures {get;}
Groups Property System.Text.RegularExpressions.GroupCollection Groups {get;}
Index Property int Index {get;}
Length Property int Length {get;}
Success Property bool Success {get;}
Value Property string Value {get;}
The Match object Contains a property called Groups which contains RegEx Group objects
("aws1288_plumber@contso.com" | Select-String "_(.*)").Matches.Groups | get-member
Results
TypeName: System.Text.RegularExpressions.Group
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Captures Property System.Text.RegularExpressions.CaptureCollection Captures {get;}
Index Property int Index {get;}
Length Property int Length {get;}
Success Property bool Success {get;}
Value Property string Value {get;}
In my case, because my regex pattern produced multiple groups, I need to specify which group I wanted. In this case group 1 holds the value of the email address. So I use the brackets to specify group 1 and .value to get the value property of the group.
("aws1288_plumber@contso.com" | Select-String "_(.*)").Matches.Groups[1].value
Results
plumber@contso.com
Line 11:
[int]$hashset[$email] += [int]$hash[$_]
This is adding the value of $hashset[$email] to $hash[$_] the problem is that at the beginning of the script, the $hash hashtable was populated with values indicated to be strings, not integers.
$hash = @{
'aws1288_plumber@contso.com'='50';
'yws3143_DBuser@contso.com'='60';
'din7412_plumber@contso.com'='30';
'tel9132_DBuser@contso.com'='10'
}
When two strings are +, they are contatenated, even if they are numbers.
IE.
'50' + '40'
Results
5040
In order to ensure that the values are seen as numbers (integers) and not strings, I “type cast” them as integers.
[int]'50' + [int]'40'
Results
90
Now when you say “I know you are piping the output of [int]$hash[$_] into the $hashset table, but not sure what the latter code set really does?”, I believe you are referring to the use of +=.
+= is a way to add something to the value you already have, rather than just overwriting it.
IE
$a = 5
$a
$a = 10
$a
$a += 5
$a
Results
5
10
15
In the above example, we first set $a to 5, as a result $a contains the value 5. We then set $a to 10, so $a contains the value of 10. Lastly we use += to add 5 to the value already stored in $a. As a result instead of $a having 5, it has 15 since it already had 10.
That is the same thing we are doing here.
[int]$hashset[$email] += [int]$hash[$_]
When we get to the “aws1288_plumber@contso.com” key in the hash table, $hashset[‘plumber@contso.com’] equals 0, and we are adding $hash[‘aws1288_plumber@contso.com’] to it which equals 50. So after this executes, $hashset[‘plumber@contso.com’] will equal 50 since 0 + 50 = 50
When we get to the “din7412_plumber@contso.com” key in the hash table, $hashset[‘plumber@contso.com’] equals 50, and we are adding $hash[‘din7412_plumber@contso.com’] to it which equals 30. So after this executes, $hashset[‘plumber@contso.com’] will equal 80 since 50 + 30 = 80
I hope that helps,
Curtis