Loading...

Follow Jason Yoder, MCT on Feedspot

Continue with Google
Continue with Facebook
or

Valid

This week I am delivering a PowerShell Toolmaking class in Phoenix.  Right now we are studying advanced functions.  While talking about the BEGIN, PROCESS, and END block, one of my future PowerShell Rock Stars gave me a great idea.  Where should a constant be created in an advanced function>

A constant is, by definition, something that cannot be changed after it is created.  So, here is how you create one.

$CONST = New-Variable -Name Constant1 -Value 10 -Option Constant

You cannot modify this constant with Set-Variable -Force and you cannot remove this constant with Remove-Variable -Force.  That is the idea.  You need to close your current scope of memory to get rid of it.

The BEGIN, PROCESS, and END blocks of an advanced function have unique capabilities.

The BEGIN block is executed when your cmdlet receives the first object in the pipeline, but before the PROCESS block is executed.  It is only ran once to allow you the opportunity to do any set up operations that the cmdlet will need to do before processing objects.

The PROCESS block is executed once for each object that is piped into your cmdlet.

The END block is executed only once when there are no more objects left in the pipeline.  This allows you to do any cleanup operations after all the work is done.

So the question is, “Do you create a constant in the BEGIN, PROCESS, or END blocks?”  Well, we are going to just not even try the END block because your constant will not be available to any other part of your code.  Let’s try building the constant in the PROCESS block.

Function Test1 {
[CmdletBinding()]
Param (
    [parameter(ValueFromPipeline=$true)]
    $Param1
)
BEGIN {}
PROCESS {$CONST = New-Variable -Name Constant1 -Value 10 -Option Constant}
END {}

}

10, 20, 30 | Test1

At this point you will receive an error because you are attempting to create multiple constants of the same name in the same scope of memory.  The first iteration worked, but all others failed.  Now for the BEGIN block

Function Test2 {
[CmdletBinding()]
Param (
    [parameter(ValueFromPipeline=$true)]
    $Param1
)
BEGIN {$CONST = New-Variable -Name Constant1 -Value 10 -Option Constant}
PROCESS {}
END {}

}

10, 20, 30 | Test2

Now it worked.  The BEGIN block is executed only once.  The constant is placed in the cmdlets scope of memory only once and it is available to the rest of the code.



  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 


Happy New Year!

Ok, that is a bit late.  I'm getting around to catching up on some questions from my classes last year.  Here is a good one.

What Will a Cmdlet Accept Through the PowerShell Pipeline? Well, that is a good question.  How a object is piped from one cmdlet to another is a touchy subject in my PowerShell classes.  This extremely powerful feature needs to be used, but the research that goes into it for new PowerShell developers can be a bit complex.  To help out, I built a cmdlet to read the help files of a cmdlet or script and determine what parameters accept pipeline input ByValue or ByPropertyName and what data type they require.  All of these are required to help the developer understand if they can pipe their objects to a cmdlet.

Here you go!  Have fun with it.


Function Get-PipelineInfo{
[CmdletBinding()]
Param (
    [String]
    $Cmdlet
)

Write-Verbose "Pipeline informaiton for $Cmdlet."
(Get-Help $Cmdlet).Parameters.Parameter |
    Where-ObjectPipelineInput -ne"False" |
    Select-Object-Property Name,
        @{N ="ByValue" ; E = { If ($_.PipelineInput -Like "*ByValue*") {$True}
                                Else {$False} }},
        @{N ="ByPropertyName" ; E = { If ($_.PipelineInput -Like "*ByPropertyName*") {$True}
                                        Else {$False} }},
        @{N ="Type"; E ={$_.Type.Name}}

<#
.SYNOPSIS
Gets the pipeline information for cmdlets.

.DESCRIPTION
Reads the help files of PowerShell scripts and cmdlets and extracts the
information on all parameters that accept information from the PowerShell
pipeline.

.PARAMETER Cmdlet
The cmdlet you want to get pipeline information on.

.EXAMPLE
Get-PipelineInfo -Cmdlet 'Get-Process'

name         pipelineInput         Type      Cmdlet    
----         -------------         ----      ------    
ComputerName True (ByPropertyName) String[]  Get-Process
Id           True (ByPropertyName) Int32[]   Get-Process
InputObject  True (ByValue)        Process[] Get-Process
Name         True (ByPropertyName) String[]  Get-Process

.NOTES
===============================================================================
== Cmdlet: Get-PipelineInfo                                                  ==
== Author: Jason A. Yoder                                                    ==
== Company: MCTExpert of Arizona                                             ==
== Date: January 15, 2019                                                    ==
== Copyright: All rights reserved.                                           ==
== Version: 1.0.0.0                                                          ==
== Legal: The user assumes all responsibility and liability for the usage of ==
== this PowerShell code.  MCTExpert of Arizona, Its officers, shareholders,  ==
== owners, and their relatives are not liable for any damages.  As with all  ==
== code, review it and understand it prior to usage.  It is recommended that ==
== this code be fully tested and validated in a test environment prior to    ==
== usage in a production environment.                                        ==
==                                                                           ==
== Does this code make changes: NO                                           ==
===============================================================================
#>
} # END: Function Get-PipelineInfo








  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Jason Yoder, MCT by Jason Yoder, Mct - 2y ago
I’m spending the week in San Diego delivering a Security+ class as part of my Annual Training for the United States Navy.  It has been a few years since my last Security+ class that I delivered to the US Air Force.  Since then, PowerShell has undergone a few version updates.  I decided to leverage one of the new cmdlets to help use demonstrate file hashing.

The group that we are working with this week is sharp and asking some really great questions.  There is a little confusion out there on what a hash is so I’m adding this to both my military and civilian Security+ classes. 

Enjoy!

<#
Demonstration of using a hashing algorithm to verify
file integrity.

ITC J. Yoder
NR SPAWAR 119

Creation Date: March 7, 2017

Slide: Symmetric Algorithms

Notes:
This code is designed to be ran inside of the PowerShell ISE.
Select the code in each step and press F8.

Tested on PowerShell 5.  Execute the command below to determine your
PowerShell version.
#>
$PSVersionTable.PSVersion

# Step 1 : Create a Folder Structure
New-Item -Pathc:\ps\Original -ItemTypeDirectory
New-Item -Pathc:\ps\Copy -ItemTypeDirectory

# Step 2 : Create a text file in the original directory.
"This is my text" | Out-File -FilePathC:\ps\Original\Data1.txt

# Step 3 : Create a hash for this file using SHA256
$HashOriginal = Get-FileHash -PathC:\ps\Original\Data1.txt

# Step 4 : View the hash.
$HashOriginal.Hash

# Step 5 : Copy the file.
Copy-Item -PathC:\ps\Original\Data1.txt -Destination C:\ps\Copy\Data1.txt

# Step 6 : Create a hash Of the copy using SHA256
$HashCopy = Get-FileHash-Path C:\ps\Copy\Data1.txt

# Step 7 : Test the hashes for equality.
$HashOriginal.Hash -eq $HashCopy.Hash

# Step 8 : Rename the copy.
Rename-item -PathC:\ps\Copy\Data1.txt -NewName C:\ps\Copy\Data2.txt

# Step 9 : Create a hash Of the renamed copy using SHA256
$HashRenamed = Get-FileHash -PathC:\ps\Copy\Data2.txt

# Step 10 : Test the hashes for equality.
$HashOriginal.Hash -eq $HashRenamed.Hash

# Step 11 : Modify the copy by adding a period to the end.
"This is my text." | Out-File -FilePathC:\ps\Copy\Data2.txt

# Step 12 : Create a hash Of the Modified copy using SHA256
$HashModified = Get-FileHash -PathC:\ps\Copy\Data2.txt

# Step 13 : Test the hashes for equality.
$HashOriginal.Hash -eq $HashModified.Hash

# Step 14 : View the hashes
Write-Host "Original : $($HashOriginal.Hash)" -BackgroundColorDarkGreen
Write-Host "Copy     : $($HashCopy.Hash)" -BackgroundColorDarkGreen
Write-Host "Renamed  : $($HashRenamed.Hash)" -BackgroundColorDarkGreen
Write-Host "Modified : $($HashModified.Hash)" -BackgroundColorDarkRed

# Step 15 : Clean up the disk.
Remove-Item -PathC:\ps\Original -Confirm:$false -Recurse
Remove-Item -PathC:\ps\Copy -Confirm:$false -Recurse


  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Separate tags by commas
To access this feature, please upgrade your account.
Start your free month
Free Preview