添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Learn How PowerShell CmdletBinding Enhances Functions

Published: 5 May 2022 - 10 min. read

  • PowerShell
  • Table of Contents

    }
    LinkedIn

    Have you ever wanted to create a PowerShell cmdlet but didn’t know C# or another Microsoft .NET Framework language? Why keep ‘wanting’ when you have PowerShell CmdletBinding at your fingertips?

    Not a reader? Watch this related video tutorial!

    There are cases where you might have so many files of different types in a directory without a good organization. Keeping your files organized is always a good practice, so you’ll create a basic function to move files by file extensions to a specified folder.

    A basic PowerShell function is not defined as having just a few lines of code. “Basic” in this context means that the function lacks the features of a PowerShell cmdlet. The function doesn’t have common parameters, and there’s no full control over the parameters available.

    1. Open Windows PowerShell ISE as administrator.

    2. Copy and paste the code below to the code editor, and run the code. The code below moves all .pdf , .doc , and .txt files on your Desktop to a single folder called Documents.

    From this point throughout this tutorial, be sure to replace ADMIN in the Desktop folder path (C:\Users\ADMIN\Desktop\) with your computer username.

    Function Group-Files
        Param(
        [string]$Path,
        [string]$Folder
        # Check if the destination folder exists. If not, then create it
        If ((Test-Path -Path ($Path + "\" + $Folder)) -eq $False) {        
            New-Item -Name $Folder -Path $Path -ItemType Directory
        # Move Items
        Get-ChildItem $Path | ForEach-Object {
    				# If the last four characters of the filename ends with .pdf, .doc, .txt
            If ($_.FullName.Substring($_.FullName.Length -4) -in ".pdf", ".doc", ".txt") 
                Move-Item -Path $_.FullName -Destination ($Path + $Folder)
    # Call the Group-Files function
    Group-Files -Path C:\Users\ADMIN\Desktop\ -Folder "Documents"
    Moving Files from Desktop to Documents Folder
    Moving Files from Desktop to Documents Folder

    After running the code above, you may have noticed that all the files just moved without asking you to confirm. Moreover, the function didn’t tell you what would happen if you ran the code. You’ll learn more about enhancing the function with CmdletBinding in the following sections.

    3. Lastly, run the Get-Command below to list all the parameters available for the Group-Files function you created.

    (Get-Command Group-Files).Parameters
    Getting Parameters for the Group-Files Function
    Getting Parameters for the Group-Files Function

    Gaining Access to Common Parameters with the CmdletBinding Attribute

    You’ve seen that a basic function works fine. But perhaps you prefer to make parameters mandatory or add a confirm action dialog box? If so, the CmdletBinding attribute will do the trick! The CmdletBinding attribute allows you to use common parameters available for PowerShell cmdlets.

    The following code represents the syntax of the CmdletBinding attribute, including all its arguments.

    [CmdletBinding( ConfirmImpact=<string>, # Default parameter set name you want PowerShell to use # if there is no parameter set. DefaultParameterSetName=<string>, # uri to online help, must begin with http or https HelpURI=<uri>, # Used when you’re trying to return data from a large database suchas MySQL. SupportsPaging=<boolean>, # Adds three parameters – First, Skip, and IncludeTotalCount to the function. SupportsShouldProcess=<boolean>, # positional binding binds positions to parameters PositionalBinding=<boolean>) as defined # It's important to use the Param keyword Param ($Parameter1) Begin{} Process{} End{}
    Function Group-Files
    {   # Set SupportsShouldProcess to True, to make -WhatIf and -Confirm accessible
        [CmdletBinding(SupportsShouldProcess=$True)]
        Param(
        [string]$Path,
        [string]$Folder
        If ($PSCmdlet.ShouldProcess($Path)) {
            Write-Host "WhatIf wasn't used, moving files..."
        Else {
            Write-Host "WhatIf has been used! Doing nothing..."
    # Calls the Grou-File function
    Group-Files -Path C:\\Users\\ADMIN\\Desktop\\ -Folder "Documents" -WhatIf
    
    Function Group-Files
    		# Set SupportsShouldProcess to True to make -WhatIf and -Confirm accessibly
        [CmdletBinding(SupportsShouldProcess=$True)]
        Param([string]$Path, [string]$Folders)
        # If the user confirmed Yes, or user didn't use -Confirm
        If ($PSCmdlet.ShouldProcess($Path)) {
            Write-Host "Files Moved"
        # If the user confirmed No
        Else {
            Write-Host "Action Declined"
    # Calls the Group-Files function
    Group-Files -Path C:\\Users\\ADMIN\\Desktop\\ -Folder "Documents" -Confirm
    
    • None – PowerShell will not prompt confirmation for any actions unless you use the -Confirm switch.
    • Low – Actions with low, medium, or high risk will be automatically confirmed.
    • Medium – The default level of the ConfirmImpact argument, where PowerShell prompts confirmation for actions with medium or high risk, such as deleting files.
    • High – PowerShell prompts the user as if the function was called with the -Confirm parameter.

    Now, run the code below to see how the ConfirmImpact argument and the preference $ConfirmPreference variable work side-by-side.

    The action of ConfirmImpact depends on the $ConfirmPreference variable’s value. You’ll get a confirmation prompt if you set the ConfirmImpact level equal to or greater than the $ConfirmPreference variable’s value.

    $ConfirmPreference='High' # Sets confirmation preference
    Function Group-Files
    		# Sets -WhatIf, -Confirm and ConfirmImpact accessible
        [CmdletBinding(SupportsShouldProcess=$True, ConfirmImpact='High')]
        Param([string]$Path, [string]$Folders)
        # If the user confirmed Yes, or user didn't use -Confirm
        If ($PSCmdlet.ShouldProcess($Path)) {
            Write-Host "Files Moved"
        # If the user confirmed No
        Else {
            Write-Host "Action Declined"
    # Calls the Group-Files function
    Group-Files -Path C:\\Users\\ADMIN\\Desktop\\ -Folder "Documents"
        Param([string]$Path, [string]$Folder)
    		Write-Verbose "Creating the folder if it doesn't exist..."
        # If the user confirmed Yes, or user didn't use -Confirm switch
        If ($PSCmdlet.ShouldProcess($Path)) {
            Write-Host "Files will be moved"
    				Write-Verbose "Moving files..."
        # If the user confirmed No
        Else {
            Write-Host "Files will not be moved"
    # Calls the Group-Files function
    Group-Files -Path C:\\Users\\ADMIN\\Desktop\\ -Folder "Documents"
    

    For instance, running the Group-Files function will not work without parameters, so you’ll set the $Path parameter as mandatory. At the same time, you’ll set a default value for the $Folders parameter.

    Below is the syntax for the Parameter attribute and all its arguments.

    Param
        [Parameter(
            Mandatory=<Boolean>,
            Position=<Integer>,
            ParameterSetName=<String>,
            ValueFromPipeline=<Boolean>,
            ValueFromPipelineByPropertyName=<Boolean>,
            ValueFromRemainingArguments=<Boolean>,
            HelpMessage=<String>,
        [string[]]
        $Parameter1
            Mandatory=$True,
            Position=0,
    				# Since the Path parameter can also get its value from a pipeline input, 
    				# provide access to the pipeline input
            ValueFromPipeline=$True,
            ValueFromPipelineByPropertyName=$True
        [string]$Path,
        [Parameter(
    				Mandatory=$False, 
    				Position=1
        [string]$Folder = "Documents" # Default value of $Folder parameter
        # If the user confirmed Yes, or user didn't use -Confirm
        If ($PSCmdlet.ShouldProcess($Path)) {
            Write-Host "Files will be moved"
    				Write-Verbose "Moving files..."
        # If the user confirmed No
        Else {Write-Host "Files will not be moved"}
    # Calls the Group-Files function without the -Path parameter
    Group-Files -Folder "Documents"
        [CmdletBinding(
            SupportsShouldProcess=$True, # Allows the use of -Confirm and -Whatif
            PositionalBinding=$True, # Binds Path and Folder by their position
            ConfirmImpact="Medium" # Confirms before moving files
        Param(
        [Parameter(
            Mandatory=$True,
            ValueFromPipeline=$True,
            ValueFromPipelineByPropertyName=$True,
            HelpMessage="Enter a source folder path"
      	# Validate the path is a folder and not a file
        [ValidateScript({Test-Path $_ -PathType Container})]
        [String]$Path,
        [Parameter(
            Mandatory=$False,
            HelpMessage="Enter a destination path"
        [ValidateCount(1,1)] # Must provide 1 argument/folder name
        [String]$Folder = "Documents"
    		Begin {
    	    # Uncomment the line below to activate -whatif
    	    # $WhatIfPreference = $True
    	    # Uncomment the line below not to ask for confirmation when moving each file
    			# $ConfirmPreference = "High"
    		# Contains the main part of the function
    	  Process { 
            # Check if folders exist. If not, then create them
            If ((Test-Path -Path ($Path + "\\" + $Folder)) -eq $False) {
                #Write-Host ($Path+"\\"+$_) does not exist!
                Write-Verbose "Creating folder $($Path+"\\"+$Folder) since it does not exist."
                New-Item -Name $Folder -Path $Path -ItemType Directory
            # Debug message
            Write-Debug "Make sure files are not opened with any program before moving."
            # If the user confirmed Yes, or user didn't use -Confirm
            If ($PSCmdlet.ShouldProcess($Path)) {
                Write-Host "Files will be moved"
                # Get all the files in the $Path directory
    						Write-Verbose "Moving files..."
                Get-ChildItem $Path | ForEach-Object {
    		        # Documents
    		        If ($_.FullName.Substring($_.FullName.Length -4) -in ".pdf", ".doc", ".txt") {
    								Write-Verbose "Moving file $($_.FullName) to $($Path + $Folder)"
    		            Move-Item -Path $_.FullName -Destination ($Path + $Folder)
            # If the user confirmed No
            Else {
                Write-Host "Files will not be moved"
    # Call the Group-Files function
    Group-Files -Verbose -Debug
      

    Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

    Explore ATA Guidebooks

    More from ATA Learning & Partners