· 4 years ago · Jun 30, 2021, 02:10 PM
1#Task 1.1: Creating a Hash Table
2
3#Create a new hash table, using key/value pairs inside of @{} that:
4#Is saved to a variable: $myHashTable
5#Has a key called "UserName" with a value of "DanPark"
6#Has a key called "ComputerName" with a value of "WIN10"
7$myHashTable = @{'UserName'='DanPark';'ComputerName'='WIN10'}
8$myHashTable
9#The command termination operator (';') is used to seperate key/value pairs within the hash table, but line breaks are usually easier to read.
10
11$EUCapitals = @{
12 'Austria' = 'Vienna'
13 'Belgium' = 'Brussels'
14 'Bulgaria' = 'Sofia'
15 'Croatia' = 'Zagreb'
16 'Czech Republic' = 'Prague'
17 'Denmark' = 'Copenhagen'
18 'Finland' = 'Helsinki'
19 'France' = 'Paris'
20 'Germany' = 'Berlin'
21}
22
23#The order the hash table is written to the console will probably not match the order they were typed.
24$EUCapitals
25
26#Use the hash table you created in the previous task, $EUCapitals, to display the capital for Finland
27$EUCapitals.Finland
28
29#Hash tables can also be accessed using dot notation. Using the key as if it were a property, will return the value associated with it.
30#Use dot notation and the previous hash table to return the capital of Finland.
31$EUCapitals['Finland']
32#This approach is convenient, but more ambiguous. Since it looks like any other object,
33#it might be harder to maintain if it is not clear that it is a hash table.
34
35#If a key doesn't exsit, NULL data will be returned instead of an error.
36#This can be seen when accessing the capital of the Netherlands from the $EUCapitals hash table.
37$EUCapitals.Netherlands
38
39#If a value is assigned to a key that does not exist, the key/value pair is added to the hash table.
40#If the key/value pair does exist, the value is updated.
41$EUCapitals.Netherlands = 'Amsterdam'
42$EUCapitals.Netherlands
43
44#The same behavior is true when using index notation, which can be seen by trying to access the "Poland" key, before and after assigning it a value.
45$EUCapitals["Poland"]
46$EUCapitals["Poland"] = 'Warsaw'
47$EUCapitals["Poland"]
48
49#Try adding a key for "Spain" with the value of "Madrid" using either approach.
50#Using Index Notation
51$EUCapitals["Spain"] = 'Madrid'
52#Using Dot Notation
53$EUCapitals.Spain = 'Madrid'
54
55<#Hash tables also have an Add() method, which will raise an error if the key is already present,
56to avoid overwritting data that is already stored. When trying to add the "Austria" key using this method,
57an error should appear, because it already exists.#>
58$EUCapitals.Add('Austria', 'Finland')
59
60#Use the Add() method to add a new key named "Sweden" with the value of "Stockholm"
61$EUCapitals.Add('Sweden','Stockholm')
62
63#Task 1.3: Hash Table Members
64
65$EUCapitals | Get-Member
66#The Remove() method can remove a key and its value. Access the "Croatia" key, then remove it.
67$EUCapitals['Croatia']
68$EUCapitals.Remove('Croatia')
69
70#TRUE and FALSE values become very useful for automation, and sometimes just knowing whether
71#something exists or not is all that is necessary. Hash tables have search options for keys or values.
72$EUCapitals.ContainsKey('Belgium')
73$EUCapitals.ContainsValue('Berlin')
74
75#Hash tables are optimized to work with keys.
76#Large data sets will perform poorly when searching for values, but with smaller data sets a performance difference won't be visible.
77$EUCapitals.Count
78#If only the keys in a hash table need to be worked with,
79#the Key property will return the list of keys, which can be useful for work on the pipeline or with other automation.
80$EUCapitals.Keys
81$EUCapitals.Keys | Sort-Object | Out-Gridview
82
83#Just like with searching, the same option exists for working with a list of the values, using a property Values.
84$EUCapitals.Values
85$EUCapitals.Values | Sort-Object | Out-Gridview
86
87#Task 1.4: Nested Hash Tables
88#The keys and values in a hash table can store any .NET object type and a single hash table can have keys and values of multiple types.
89$APCapitals = @{
90 'China' = 'Beijing'
91 'Indonesia' = 'Jakarta'
92 'Japan' = 'Tokyo'
93 'Malaysia' = 'Kuala Lumpur'
94 'Singapore' = 'Singapore'
95 'South Korea' = 'Seoul'
96 'Taiwan' = 'Taipei'
97 'Vietnam' = 'Hanoi'
98}
99
100$SACapitals = @{
101 'Chile' = 'Santiago'
102 'Peru' = 'Lima'
103 'Brazil' = 'Brasilia'
104 'Equador' = 'Quito'
105 'Venezuela' = 'Caracas'
106 'Falkland Islands' = 'Stanley'
107 'Uruguay' = 'Montevideo'
108 'Argentina' = 'Buenos Aires'
109 'Guyana' = 'Georgetown'
110 'Paraquay' = 'Asuncion'
111}
112#Before creating a nested hash table, create a new empty hash table called: $WorldCapitals.
113$WorldCapitals = @{}
114
115#The new hash table can contain key/value pairs that use the previously created hash tables as the values.
116#Assign the previous hash tables as values within the Capitals hash table with the following key/value pairs:
117#Index notation, dot notation, and the Add() method can all accomplish this goal
118$WorldCapitals.Add("EU",$EUCapitals) # Add notation
119$WorldCapitals["AP"]= $APCapitals # Index notation
120$WorldCapitals.SA = $SACapitals # dot notation
121
122$WorldCapitals.EU
123#To view the values of the nested hash tables you would append the secondary key to the first.
124#This can be done by using either dot notation or index notation.
125#Try returning the values for the capitals of Finland, Denmark, Taiwan, and Brazil
126$WorldCapitals.EU.Finland
127$WorldCapitals.EU["Denmark"]
128$WorldCapitals["AP"].'Taiwan'
129$WorldCapitals["SA"]["Brazil"]
130
131# Exercise 2: Hash Table Usage
132
133# Task 2.1: Calculated Properties
134<#PowerShell provides the ability to dynamically add new properties and alter the formatting of objects output to the pipeline.
135These are created with hash tables and known as calculated properties.
136Calculated properties are used to create a new property during pipeline operations.
137To make the property, a hash table with 2 key/value pairs is required.#>
138
139
140#Create a variable named $TestProp, that has a hash table for a basic calculated property matching this table:
141$TestProp = @{
142Name="NewProperty"
143Expression= {"Calculated Value"}
144}
145
146#In order to use the calculated property, one of the supported cmdlets has to be used, such as Format-Table.
147#Use Get-ChildItem to look at all the files in C:\Windows, then use Format-Table to display the name, length, and $TestProp properties.
148Get-ChildItem C:\Windows -File | Format-Table Name, Length, $TestProp
149
150#Notice that every file was assigned a property named NewProperty,
151#which has the "Calculated Value" string from the $TestProperty hash table.
152#Plain strings for values are not very useful, but the script blocks can be used to interact with each object's properties and methods.
153
154#The length property in the earlier output is the file size.
155#File sizes can be frustrating in PowerShell because they are displayed in bytes.
156#A calculated property can be used to calculate the value as kilobytes or any other multiplier.
157#Try executing the following code to see what that looks like:
158$kb = @{
159 Name = "kb"
160 Expression = {$_.Length / 1kb}
161}
162Get-ChildItem C:\Windows -File | Format-Table Name, Length, $kb
163
164#Calculated properties are only supported by a small list of cmdlets,
165#which are focused on sorting, and formatting data on the pipeline. A list of the cmdlets can be found in the documentation
166
167<#
168Goal: Find the age, in days, of each item in the C:\Windows directory.
169
170Hints
171
172$_ can be used inside the expression script block to represent the object
173Get-Date can find the current date and time as a DateTime object
174The CreationTime property on files and directories will also be DateTime objects
175DateTimes can be subtracted from one another
176DateTimes have a Days property
177#>
178#option 1
179$Age = @{
180 Name='Age(Days)'
181 Expression={((Get-Date)-$_.CreationTime).Days}
182}
183Get-ChildItem C:\Windows | Format-Table Name,$Age
184
185#option 2
186$dateBlock = {
187 $Date = Get-Date
188 $Difference = $date - $_.CreationTime
189 $Difference.days
190}
191
192$Age = @{
193 Name='Age(Days)'
194 Expression=$dateBlock
195}
196Get-ChildItem C:\Windows | Format-Table Name,$Age
197
198#Task 2.2: New-Object Properties
199#PowerShell has special PSCustomObject class that exists specifically to be used with hash tables.
200#Using this class with a hash table will allow you to create your own objects with specified properties.
201
202$MyProperties = @{
203 Name = "Nichole Norris"
204 UserName = "NNorris"
205 Division = 'IT'
206 Laptop = 'Surface'
207 Office = "Remote"
208}
209
210$MyProperties
211$MyProperties.GetType().FullName
212$MyProperties | Get-Member
213
214<#If someone recieves a hash table from a function or cmdlet, and sends it into Get-Member, it doesn't give them convenient information to read through.
215Instead, a custom object can be used. New-Object allows specifying any .NET object type, and providing a hash table of appropriate properties.
216PSCustomObject is a data type made specifically to recieve any properties and make a custom object.#>
217$MyUserObject = New-Object -TypeName PSCustomobject -Property $MyProperties
218
219#Write $MyUserObject out to the console to see that it will display as a format list (or table)
220#instead of the way the hash table was displayed previously. Then, check the type.
221$MyUserObject
222$MyUserObject.GetType().FullName
223
224#If this is used as the output of a function, then the reciever can pipe directly to Get-Member and see the available properties
225$MyUserObject | Get-Member
226
227#There is a more convenient technique than using New-Object, by using a shortcut called typecasting.
228#This is covered in detail in another section, but can be seen in this example:
229$MyUserObject2 = [PSCustomObject]$MyProperties
230$MyUserObject2
231$MyUserObject2.GetType().FullName
232
233#When creating a hash table, the values do not have to be staticly defined, they can also accept objects from cmdlets.
234#Try running the below to create another custom object.
235$System = [PSCustomObject]@{
236 "Static" = "Static Value"
237 "Service" = Get-Service -Name WinRM
238 "Process" = Get-Process -Name Idle
239 "Files" = Get-ChildItem c:\Windows -File
240}
241$System
242$System | FL
243
244$System.Static
245$System.Service
246$System.Process
247$System.Files
248#Pipe $System into Get-Member and notice the data types for the property definitions.
249$System | Get-Member
250
251#Task 2.3: Splatting
252#Splatting allows definining parameter values in a hash table as key/value pairs in an easy to read column, then providing those values to a cmdlet.
253#To use splatting you need to save the the parameter names and parameter values in the key/value structure of a hash table.
254#Create a hash table named $Params with the following parameter names and values that will be used with the Get-ChildItem cmdlet.
255$Params = @{
256 Path = 'C:\Windows\System32\WindowsPowerShell\v1.0'
257 Filter = '*.ps1'
258 Recurse = $true
259 Name = $true
260}
261
262#Because some cmdlets will want to use positional parameters that recieve hash tables,
263#and all cmdlets need to support splatting, the $ isn't used.
264#Instead, the @ symbol is used to tell the cmdlet to turn all the key/value pairs into parameters and their values.
265Get-ChildItem @Params
266
267#Cmdlets can also accept additional parameters along with the parameters supplied by the hash table.
268#Run the previous command and use the Exclude any files that contain Profile.
269Get-ChildItem @Params -Exclude *Profile*
270$SplatOutput
271
272#Task 2.4: Default Parameter Values
273<#The $PSDefaultParameterValues variable can specify custom default values for parameters on any cmdlet or advanced function.
274Cmdlets and functions use the custom default value unless you specify another value in the command.#>
275
276Write-Host "Hello World"
277#Add a key for Write-Host to set the default ForegroundColor parameter value to Cyan
278$PSDefaultParameterValues["Write-Host:ForegroundColor"] = "Cyan"
279Write-Host Test
280
281Test-Connection -ComputerName "MS"
282
283#Add a key to set the default for Test-Connection that has the Quiet parameter set to $True
284$PSDefaultParameterValues.Add('Test-Connection:Quiet',$True)
285Test-Connection -ComputerName "MS"
286
287$PSDefaultParameterValues.Clear()
288Write-Host "Hello World"
289Test-Connection -ComputerName "MS"
290#$PSDefaultPatameterValues does not persist state across PowerShell sessions, so it needs to be defined each time, or put inside of a profile.