From f3bac7faf0c6588a0b9aab48c0418f02a0d2bc9f Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Fri, 29 Jul 2016 07:23:11 -0500 Subject: [PATCH 01/12] demo PowerShellGet repositories --- demos/powershellget/PowerShellGet.ps1 | 33 ++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/demos/powershellget/PowerShellGet.ps1 b/demos/powershellget/PowerShellGet.ps1 index 37bdd29690..0da9c3bf08 100644 --- a/demos/powershellget/PowerShellGet.ps1 +++ b/demos/powershellget/PowerShellGet.ps1 @@ -31,16 +31,25 @@ Uninstall-Script Fabrikam-Script -Verbose #endregion -#region Using PowerShellGet find and install other demos +#region Using PowerShellGet find and install modules # Value: equivalent of pypi # Look for all the modules we'll be demoing today Find-Module -Tag 'PowerShellCore_Demo' +# Save module to specified location +Save-Module -Tag 'PowerShellCore_Demo' -Path /tmp + # Pipe this to Install-Module to install them Find-Module -Tag 'PowerShellCore_Demo' | Install-Module -Verbose Get-InstalledModule +# Update all installed modules +Update-Module + +#endregion + +#region Using PowerShellGet with tags # Look for all the scripts we'll be demoing today Find-Script -Tag 'PowerShellCore_Demo' @@ -50,3 +59,25 @@ Find-Script -Tag 'PowerShellCore_Demo' | Install-Script -Verbose Get-InstalledScript #endregion + +#region Working with PowerShellGet repositories + +# List available PS repositories +Get-PSRepository + +# Publish script to the PS Gallery +Publish-Script -Path C:\Demo.ps1 -NuGetApiKey 1234 -Repository PSGallery -WhatIf + +# Publish module to PS Gallery +Publish-Module -Name Demo -RequiredVersion 0.1 -NuGetApiKey 1234 -Repository PSGallery -WhatIf + +# Register a new private feed +Register-PSRepository -Name "myPrivateGallery" –SourceLocation "https://www.myget.org/F/powershellgetdemo/api/v2" -PublishLocation "https://www.myget.org/F/powershellgetdemo/api/v2/Packages" -InstallationPolicy Trusted + +# Change the trust level for a repositories +Set-PSRepository -Name "myPrivateGallery" -InstallationPolicy "Untrusted" + +# Remove a private feed +Unregister-PSRepository -Name "myPrivateGallery" + +#endregion \ No newline at end of file From 8e9100ae4a815eda6b26bf60bb90a4f8219b590e Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Fri, 29 Jul 2016 13:04:33 -0500 Subject: [PATCH 02/12] page to describe creating and working with simple script files --- .../create-powershell-scripts.md | 61 +++++++++++++++++++ .../powershell-beginners-guide.md | 8 --- 2 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 docs/learning-powershell/create-powershell-scripts.md diff --git a/docs/learning-powershell/create-powershell-scripts.md b/docs/learning-powershell/create-powershell-scripts.md new file mode 100644 index 0000000000..e89fa1b59b --- /dev/null +++ b/docs/learning-powershell/create-powershell-scripts.md @@ -0,0 +1,61 @@ +How to Create and Run PowerShell scripts +==== + +You can combine a series of commands in a text file and save it with the file extension '.ps1', and the file will become a PowerShell script. +This would begin by opening your favorite text editor and pasting in the following example. + +``` PowerShell +# Script to return current IPv4 addresses on a Linux or MacOS host +$ipInfo = ifconfig | select-string 'inet' +$ipInfo = [regex]::matches($ipInfo,"addr:\b(?:\d{1,3}\.){3}\d{1,3}\b") | ForEach-Object value +foreach ($ip in $ipInfo) { + $ip.replace('addr:','') +} +``` + +Then save the file to something memorable, such as .\NetIP.ps1. +In the future when you need to get the IP addresses for the node, you can simplify this task by executing the script. + +``` PowerShell +PS>.\NetIP.ps1 +10.0.0.1 +127.0.0.1 +``` +You can accomplish this same task on Windows. + +```PowerShell +# One line script to return current IPv4 addresses on a Windows host +Get-NetIPAddress | Where-Object {$_.AddressFamily -eq 'IPv4'} | ForEach-Object IPAddress +``` +As before, save the file as .\NetIP.ps1 and execute within a PowerShell environment. +Note: If you are using Windows, make sure you set the PowerShell's execution policy to "RemoteSigned" in this case. +See [Running PowerShell Scripts Is as Easy as 1-2-3](run-ps) for more details. + +```PowerShell +PS C:\NetIP.ps1 +127.0.0.1 +10.0.0.1 +``` + +Creating a script that can accomplish the same task on multiple operating systems +---- + +If you would like to author one script that will return the IP address across Linux, MacOS, or Windows, you could accomplish this using an IF statement. + +```PowerShell +# Script to return current IPv4 addresses for Linux, MacOS, or Windows +$IP = if ($IsLinux -or $IsOSX) { + $ipInfo = ifconfig | select-string 'inet' + $ipInfo = [regex]::matches($ipInfo,"addr:\b(?:\d{1,3}\.){3}\d{1,3}\b") | ForEach-Object value + foreach ($ip in $ipInfo) { + $ip.replace('addr:','') + } +} +else { + Get-NetIPAddress | Where-Object {$_.AddressFamily -eq 'IPv4'} | ForEach-Object IPAddress +} + +# Remove loopback address from output regardless of platform +$IP | Where-Object {$_ -ne '127.0.0.1'} +``` +[run-ps]:http://windowsitpro.com/powershell/running-powershell-scripts-easy-1-2-3 \ No newline at end of file diff --git a/docs/learning-powershell/powershell-beginners-guide.md b/docs/learning-powershell/powershell-beginners-guide.md index a4046fbce4..c253d185d6 100644 --- a/docs/learning-powershell/powershell-beginners-guide.md +++ b/docs/learning-powershell/powershell-beginners-guide.md @@ -259,15 +259,7 @@ Mode LastWriteTime Length Name -a---- 5/16/2016 1:15 PM 32972 test.log ``` -How to Create and Run PowerShell scripts ----- -- You can use ISE, Visual Studio Code or your favorite editor to create a PowerShell script and save the script with a .ps1 file extension (for example, helloworld.ps1) -- To run the script, cd to your current folder and type ./yourscript.ps1 (for example, ./helloworld.ps1). -Note: If you are using Windows, make sure you set the PowerShell's execution policy to "RemoteSigned" in this case. -See [Running PowerShell Scripts Is as Easy as 1-2-3] [run-ps] for more details. - -[run-ps]:http://windowsitpro.com/powershell/running-powershell-scripts-easy-1-2-3 Recommended Training and Reading ---- From 53f8cdb29cb290d7182a08d7477a956f6cd4652d Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Fri, 29 Jul 2016 15:02:34 -0500 Subject: [PATCH 03/12] example formattting --- docs/learning-powershell/powershell-beginners-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learning-powershell/powershell-beginners-guide.md b/docs/learning-powershell/powershell-beginners-guide.md index c253d185d6..ab7ed43732 100644 --- a/docs/learning-powershell/powershell-beginners-guide.md +++ b/docs/learning-powershell/powershell-beginners-guide.md @@ -213,7 +213,7 @@ PS /> Get-Help -Name Get-Process It displays the examples how to use the Get-Process cmdlet. ```PowerShell -PS />**Get-Help -Name Get-Process -Examples** +PS />Get-Help -Name Get-Process -Examples ``` If you use **-Full** parameter, for example, `Get-Help -Name Get-Process -Full`, it will display more technical information. From 362eef0c6e3bf19c1e6014ae1dee26cdcf442d84 Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Sat, 30 Jul 2016 08:20:11 -0500 Subject: [PATCH 04/12] remove publish commands and correct formatting of example --- demos/powershellget/PowerShellGet.ps1 | 6 ------ .../powershell-beginners-guide.md | 13 ++++++++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/demos/powershellget/PowerShellGet.ps1 b/demos/powershellget/PowerShellGet.ps1 index 0da9c3bf08..fb99a49fcf 100644 --- a/demos/powershellget/PowerShellGet.ps1 +++ b/demos/powershellget/PowerShellGet.ps1 @@ -65,12 +65,6 @@ Get-InstalledScript # List available PS repositories Get-PSRepository -# Publish script to the PS Gallery -Publish-Script -Path C:\Demo.ps1 -NuGetApiKey 1234 -Repository PSGallery -WhatIf - -# Publish module to PS Gallery -Publish-Module -Name Demo -RequiredVersion 0.1 -NuGetApiKey 1234 -Repository PSGallery -WhatIf - # Register a new private feed Register-PSRepository -Name "myPrivateGallery" –SourceLocation "https://www.myget.org/F/powershellgetdemo/api/v2" -PublishLocation "https://www.myget.org/F/powershellgetdemo/api/v2/Packages" -InstallationPolicy Trusted diff --git a/docs/learning-powershell/powershell-beginners-guide.md b/docs/learning-powershell/powershell-beginners-guide.md index ab7ed43732..0db38cc67c 100644 --- a/docs/learning-powershell/powershell-beginners-guide.md +++ b/docs/learning-powershell/powershell-beginners-guide.md @@ -213,7 +213,7 @@ PS /> Get-Help -Name Get-Process It displays the examples how to use the Get-Process cmdlet. ```PowerShell -PS />Get-Help -Name Get-Process -Examples +PS />Get-Help -Name Get-Process -Examples** ``` If you use **-Full** parameter, for example, `Get-Help -Name Get-Process -Full`, it will display more technical information. @@ -260,6 +260,17 @@ Mode LastWriteTime Length Name ``` +Working with Objects +---- +When cmdlets are executed in PowerShell, the output is an Object, as opposed to just text. +This provides the ability to store a lot of information + +Discovering available Methods +---- + +PowerShell Functions +---- + Recommended Training and Reading ---- From 1acc7175da64ba2fe67e4a5b758400e6de4dd8aa Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Sat, 30 Jul 2016 08:21:07 -0500 Subject: [PATCH 05/12] caps for cmdlet --- docs/learning-powershell/create-powershell-scripts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/learning-powershell/create-powershell-scripts.md b/docs/learning-powershell/create-powershell-scripts.md index e89fa1b59b..50d272267a 100644 --- a/docs/learning-powershell/create-powershell-scripts.md +++ b/docs/learning-powershell/create-powershell-scripts.md @@ -6,7 +6,7 @@ This would begin by opening your favorite text editor and pasting in the followi ``` PowerShell # Script to return current IPv4 addresses on a Linux or MacOS host -$ipInfo = ifconfig | select-string 'inet' +$ipInfo = ifconfig | Select-String 'inet' $ipInfo = [regex]::matches($ipInfo,"addr:\b(?:\d{1,3}\.){3}\d{1,3}\b") | ForEach-Object value foreach ($ip in $ipInfo) { $ip.replace('addr:','') @@ -45,7 +45,7 @@ If you would like to author one script that will return the IP address across Li ```PowerShell # Script to return current IPv4 addresses for Linux, MacOS, or Windows $IP = if ($IsLinux -or $IsOSX) { - $ipInfo = ifconfig | select-string 'inet' + $ipInfo = ifconfig | Select-String 'inet' $ipInfo = [regex]::matches($ipInfo,"addr:\b(?:\d{1,3}\.){3}\d{1,3}\b") | ForEach-Object value foreach ($ip in $ipInfo) { $ip.replace('addr:','') From 708f32cca4e840e91888457061b1244a89ba2179 Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Sat, 30 Jul 2016 08:23:14 -0500 Subject: [PATCH 06/12] spaces in prompt examples --- docs/learning-powershell/create-powershell-scripts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/learning-powershell/create-powershell-scripts.md b/docs/learning-powershell/create-powershell-scripts.md index 50d272267a..e9aa6170eb 100644 --- a/docs/learning-powershell/create-powershell-scripts.md +++ b/docs/learning-powershell/create-powershell-scripts.md @@ -17,7 +17,7 @@ Then save the file to something memorable, such as .\NetIP.ps1. In the future when you need to get the IP addresses for the node, you can simplify this task by executing the script. ``` PowerShell -PS>.\NetIP.ps1 +PS> .\NetIP.ps1 10.0.0.1 127.0.0.1 ``` @@ -32,7 +32,7 @@ Note: If you are using Windows, make sure you set the PowerShell's execution pol See [Running PowerShell Scripts Is as Easy as 1-2-3](run-ps) for more details. ```PowerShell -PS C:\NetIP.ps1 +PS C:\> NetIP.ps1 127.0.0.1 10.0.0.1 ``` From 5e2493a7e8a464da51de7eb4a63116f086ea1aa1 Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Sat, 30 Jul 2016 08:23:46 -0500 Subject: [PATCH 07/12] caps in title --- docs/learning-powershell/create-powershell-scripts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learning-powershell/create-powershell-scripts.md b/docs/learning-powershell/create-powershell-scripts.md index e9aa6170eb..a062ec7457 100644 --- a/docs/learning-powershell/create-powershell-scripts.md +++ b/docs/learning-powershell/create-powershell-scripts.md @@ -1,4 +1,4 @@ -How to Create and Run PowerShell scripts +How to Create and Run PowerShell Scripts ==== You can combine a series of commands in a text file and save it with the file extension '.ps1', and the file will become a PowerShell script. From d6a1df3e9b9139ff82925da7fbae6513636758d1 Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Tue, 2 Aug 2016 08:15:36 -0500 Subject: [PATCH 08/12] Working with PowerShell Objects --- .../working-with-powershell-objects.md | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 docs/learning-powershell/working-with-powershell-objects.md diff --git a/docs/learning-powershell/working-with-powershell-objects.md b/docs/learning-powershell/working-with-powershell-objects.md new file mode 100644 index 0000000000..d747ec02f0 --- /dev/null +++ b/docs/learning-powershell/working-with-powershell-objects.md @@ -0,0 +1,124 @@ +Working with PowerShell Objects +==== +When cmdlets are executed in PowerShell, the output is an Object, as opposed to only returning text. +This provides the ability to store information as properties. +As a result, handling large amounts of data and getting only specific properties is a trivial task. + +As a simple example, the following function retrieves information about storage Devices on a Linux or MacOS operating system platform. +This is accomplished by parsing the output of an existing command, *parted -l* in administrative context, and creating an object from the raw text by using the *New-Object* cmdlet. + +```PowerShell +Function Get-DiskInfo { + $disks = sudo parted -l | Select-String "Disk /dev/sd*" -context 1,0 + $diskinfo = @() + foreach ($disk in $disks) { + $diskline1 = $disk.ToString().Split("`n")[0].ToString().Replace(' Model: ','') + $diskline2 = $disk.ToString().Split("`n")[1].ToString().Replace('> Disk ','') + $i = New-Object psobject -Property @{'Friendly Name' = $diskline1; Device=$diskline2.Split(': ')[0]; 'Total Size'=$diskline2.Split(':')[1]} + $diskinfo += $i + } + $diskinfo +} +``` + +Execute the function and store the results as a variable. +Now retrieve the value of the variable. +The results are formatted as a table with the default view. + +*Note: in this example, the disks are virtual disks in a Microsoft Azure virtual machine.* + +```PowerShell +PS /home/psuser> $d = Get-DiskInfo +[sudo] password for psuser: +PS /home/psuser> $d + +Friendly Name Total Size Device +------------- ---------- ------ +Msft Virtual Disk (scsi) 31.5GB /dev/sda +Msft Virtual Disk (scsi) 145GB /dev/sdb + +``` + +Passing the variable down the pipeline to *Get-Member* reveals available methods and properties. +This is because the value of *d$* is not just text output. +The value is actually an array of .Net objects with methods and properties. +The properties include Device, Friendly Name, and Total Size. + +```PowerShell +PS /home/psuser> $d | Get-Member + + + TypeName: System.Management.Automation.PSCustomObject + +Name MemberType Definition +---- ---------- ---------- +Equals Method bool Equals(System.Object obj) +GetHashCode Method int GetHashCode() +GetType Method type GetType() +ToString Method string ToString() +Device NoteProperty string Device=/dev/sda +Friendly Name NoteProperty string Friendly Name=Msft Virtual Disk (scsi) +Total Size NoteProperty string Total Size= 31.5GB +``` + +To confirm, we can call the GetType() method interactively from the console. + +```PowerShell +PS /home/psuser> $d.GetType() + +IsPublic IsSerial Name BaseType +-------- -------- ---- -------- +True True Object[] System.Array +``` + +To index in to the array and return only specific objects, use the square brackets. + +```PowerShell +PS /home/psuser> $d[0] + +Friendly Name Total Size Device +------------- ---------- ------ +Msft Virtual Disk (scsi) 31.5GB /dev/sda + +PS /home/psuser> $d[0].GetType() + +IsPublic IsSerial Name BaseType +-------- -------- ---- -------- +True False PSCustomObject System.Object +``` + +To return a specific property, the property name can be called interactively from the console. + +```PowerShell +PS /home/psuser> $d.Device +/dev/sda +/dev/sdb +``` + +To output a view of the information other than default, such as a view with only specific properties selected, pass the value to the *Select-Object* cmdlet. + +```PowerShell +PS /home/psuser> $d | Select-Object Device, 'Total Size' + +Device Total Size +------ ---------- +/dev/sda 31.5GB +/dev/sdb 145GB +``` + +Finally, the example below demonstrates use of the *ForEach-Object* cmdlet to iterate through the array and manipulate the value of a specific property of each object. +In this case the Total Size property, which was given in Gigabytes, is changed to Megabytes. +Alternatively, index in to a position in the array as shown below in the third example. + +```PowerShell +PS /home/psuser> $d | ForEach-Object 'Total Size' + 31.5GB + 145GB + +PS /home/psuser> $d | ForEach-Object {$_.'Total Size' / 1MB} +32256 +148480 + +PS /home/psuser> $d[1].'Total Size' / 1MB +148480 +``` \ No newline at end of file From bf22db9d68c472f57ff619f1ae96baa21ae02b24 Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Tue, 2 Aug 2016 08:38:45 -0500 Subject: [PATCH 09/12] Context caps --- docs/learning-powershell/working-with-powershell-objects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learning-powershell/working-with-powershell-objects.md b/docs/learning-powershell/working-with-powershell-objects.md index d747ec02f0..07c81b1984 100644 --- a/docs/learning-powershell/working-with-powershell-objects.md +++ b/docs/learning-powershell/working-with-powershell-objects.md @@ -9,7 +9,7 @@ This is accomplished by parsing the output of an existing command, *parted -l* i ```PowerShell Function Get-DiskInfo { - $disks = sudo parted -l | Select-String "Disk /dev/sd*" -context 1,0 + $disks = sudo parted -l | Select-String "Disk /dev/sd*" -Context 1,0 $diskinfo = @() foreach ($disk in $disks) { $diskline1 = $disk.ToString().Split("`n")[0].ToString().Replace(' Model: ','') From cdb925f1fe2531a8d8a4a736714fc1e84cff1b9f Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Tue, 2 Aug 2016 08:39:24 -0500 Subject: [PATCH 10/12] correct type in d$ --- docs/learning-powershell/working-with-powershell-objects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learning-powershell/working-with-powershell-objects.md b/docs/learning-powershell/working-with-powershell-objects.md index 07c81b1984..adbdc3eeef 100644 --- a/docs/learning-powershell/working-with-powershell-objects.md +++ b/docs/learning-powershell/working-with-powershell-objects.md @@ -40,7 +40,7 @@ Msft Virtual Disk (scsi) 145GB /dev/sdb ``` Passing the variable down the pipeline to *Get-Member* reveals available methods and properties. -This is because the value of *d$* is not just text output. +This is because the value of *$d* is not just text output. The value is actually an array of .Net objects with methods and properties. The properties include Device, Friendly Name, and Total Size. From 002adc283b927fdd52e107fd341f9e477d480752 Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Tue, 2 Aug 2016 08:41:22 -0500 Subject: [PATCH 11/12] caps .Replace --- docs/learning-powershell/create-powershell-scripts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/learning-powershell/create-powershell-scripts.md b/docs/learning-powershell/create-powershell-scripts.md index a062ec7457..a530eba792 100644 --- a/docs/learning-powershell/create-powershell-scripts.md +++ b/docs/learning-powershell/create-powershell-scripts.md @@ -9,7 +9,7 @@ This would begin by opening your favorite text editor and pasting in the followi $ipInfo = ifconfig | Select-String 'inet' $ipInfo = [regex]::matches($ipInfo,"addr:\b(?:\d{1,3}\.){3}\d{1,3}\b") | ForEach-Object value foreach ($ip in $ipInfo) { - $ip.replace('addr:','') + $ip.Replace('addr:','') } ``` @@ -48,7 +48,7 @@ $IP = if ($IsLinux -or $IsOSX) { $ipInfo = ifconfig | Select-String 'inet' $ipInfo = [regex]::matches($ipInfo,"addr:\b(?:\d{1,3}\.){3}\d{1,3}\b") | ForEach-Object value foreach ($ip in $ipInfo) { - $ip.replace('addr:','') + $ip.Replace('addr:','') } } else { From b92791216b36bf2a294c58800ac5177292a7e7e1 Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Tue, 2 Aug 2016 15:09:32 -0500 Subject: [PATCH 12/12] remove -PublishLocation --- demos/powershellget/PowerShellGet.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/powershellget/PowerShellGet.ps1 b/demos/powershellget/PowerShellGet.ps1 index fb99a49fcf..d371a7d42a 100644 --- a/demos/powershellget/PowerShellGet.ps1 +++ b/demos/powershellget/PowerShellGet.ps1 @@ -66,7 +66,7 @@ Get-InstalledScript Get-PSRepository # Register a new private feed -Register-PSRepository -Name "myPrivateGallery" –SourceLocation "https://www.myget.org/F/powershellgetdemo/api/v2" -PublishLocation "https://www.myget.org/F/powershellgetdemo/api/v2/Packages" -InstallationPolicy Trusted +Register-PSRepository -Name "myPrivateGallery" –SourceLocation "https://www.myget.org/F/powershellgetdemo/api/v2" -InstallationPolicy Trusted # Change the trust level for a repositories Set-PSRepository -Name "myPrivateGallery" -InstallationPolicy "Untrusted"