Positional parameters

Positional parameters have been around since the beginning of PowerShell. Positional parameters assume the parameter you mean from the position of the value in the command you supply. For instance you can do this:

Get-ChildItem -Path C:\test\ -Filter *.xml

Path and filter are the 2 positional parameters for Get-ChildItem (cmdlets can have 0, 1 or many positional parameters) so you can also do this:

Get-ChildItem C:\test\  *.xml

If you reverse the values you get an error

PS> Get-ChildItem *.xml  C:\test\
Get-ChildItem : Second path fragment must not be a drive or UNC name.
Parameter name: path2
At line:1 char:1
+ Get-ChildItem *.xml  C:\test\
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (C:\Scripts:String) [Get-ChildItem], ArgumentException
    + FullyQualifiedErrorId : DirArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand

You can find the position parameters by looking in the help file

PS> Get-Help Get-ChildItem -Parameter path

-Path <String[]>
    Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory
    (.).

    Required?                    false
    Position?                    0
    Default value                Current directory
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  false

PS> Get-Help Get-ChildItem -Parameter filter

-Filter <String>
    Specifies a filter in the provider's format or language. The value of this parameter qualifies the Path parameter.
    The syntax of the filter, including the use of wildcards, depends on the provider. Filters are more efficient than
    other parameters, because the provider applies them when retrieving the objects, rather than having Windows
    PowerShell filter the objects after they are retrieved.

    Required?                    false
    Position?                    1
    Default value                None
    Accept pipeline input?       False
    Accept wildcard characters?  false

Notice the position values. A parameter that has to be named i.e. non-positional will have Named as the value for position:

PS> Get-Help Get-ChildItem -Parameter include

-Include <String[]>
    Specifies, as a string array, an item or items that this cmdlet includes in the operation. The value of this parameter qualifies the Path parameter. Enter a path element or pattern, such as *.txt. Wildcards are permitted.

    The Include parameter is effective only when the command includes the Recurse parameter or the path leads to the contents of a directory, such as C:\Windows\*, where the wildcard character specifies the contents of the  C:\Windows directory.

    Required?                    false
    Position?                    named
    Default value                None
    Accept pipeline input?       False
    Accept wildcard characters?  false

You can also identify positional parameters from the syntax listing

Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Attributes {ReadOnly | Hidden | System | Directory | Archive | Device | Normal | Temporary | SparseFile | ReparsePoint | Compressed | Offline | NotContentIndexed | Encrypted | IntegrityStream | NoScrubData}] [-Depth <UInt32>] [-Directory] [-Exclude <String[]>] [-File] [-Force]
[-Hidden] [-Include <String[]>] [-Name] [-ReadOnly] [-Recurse] [-System] [-UseTransaction] [<CommonParameters>]

The name of positional parameters are surrounded by square brackets

A question on the forum noted that the help file about_parameters states that positional parameters are numbers 1,2,3… and named parameters are effectively numbered 0 BUT the help file for Get-ChildItem numbers the positional parameters as 0 & 1

What’s happening?

If I remember correctly originally positional parameters were numbered from 1 but that was changed so 0 didn’t mean named. Looks like the about file didn’t get updated.

We can test this this with a function:

function test-pp {
 [CmdletBinding()]
 param (
   [Parameter(Position=0)]
   [int]$x,

   [Parameter(Position=1)]
   [string]$y
 )

"$x is a number"
 "$y is a string"
}

PS> test-pp -x 2 -y abc
2 is a number
abc is a string

PS> test-pp 2 abc
2 is a number
abc is a string

So using position 0 works for positional parameters. What if we number them 1 & 2

function test-pp {
 [CmdletBinding()]
 param (
   [Parameter(Position=1)]
   [int]$x,

   [Parameter(Position=2)]
   [string]$y
 )

"$x is a number"
 "$y is a string"
}

PS> test-pp -x 2 -y abc
2 is a number
abc is a string

PS> test-pp 2 abc
2 is a number
abc is a string

Works as well.

I’d recommend starting your positional parameter numbering from 0 and assume that about_parameters needs updating

Posted in Powershell | Leave a comment

ISE or VS code?

When PowerShell v2 shipped with the ISE it was seen as a great step forward. We now had a decent editor for creating PowerShell code and running that code. You could also invoke the debugger. Some extensions to ISE have occurred, most notably  Show-Command, but its essentially the same editor as in PowerShell v2

Visual Studio Code – now at version 1.11.2 – offers an interesting alternative. It manages a host of other languages as well as PowerShell. I currently have the extensions for Docker, Markdown, SQL, PowerShell, JSON and XML loaded. Many others are available as open source projects.

You can also open a terminal window which can be a command prompt, PowerShell or WSL bash – you could have all 3 open simultaneously if required.

The other big plus is that VS Code is cross platform so I can use the same editor on Windows and Linux. A big plus in these days of heterogeneous environments.

I’m going to try using VS Code instead of ISE for a while to see if it suits the way I work. If so it’ll become my default editor

Posted in Powershell | 3 Comments

IT Professional?

Way back when we were known as Administrators. Then the term IT Professional (often irritatingly shortened to IT Pro) appeared. We’re doing the same job but have a fancy new title.

Are System Administrators really professionals in the true sense of the word.

I would argue no.

– We don’t have universally recognised certification/qualification requirement

– We don’t have a professional body

– We don’t have an continuous learning requirement to maintain the title

– We don’t have a recognised body of knowledge that accurately defines how and what we should do

You may argue with these points and say for instance that you do keep learning – congratulations – you’re in the minority that does.

We have partial answers to my points for instance vendor certifications and best practice documentation but at the moment its all very piecemeal.

If IT wants to be treated as a profession its practitioners have to behave as professionals and at the moment I don’t think that happens in the vast majority of cases. There are exceptions and hopefully over time that behaviour will become the norm. Until then I’m going to stick with Administrators.

Posted in Opinion | 3 Comments

DevOps ebook

DevOps is the latest “big thing” in IT. Whether it will make a difference or be dropped as everyone rushes to embrace the next “big thing” only time will tell.

For now, there’s a free ebook from the DevOps Collective (the people who bring you the PowerShell Summit) that looks at DevOps from the OPs perspective:

https://www.gitbook.com/book/devopscollective/devops-the-ops-perspective/details

Posted in DevOps | Leave a comment

DSC Configuring Sharing

A new set of repositories on Github document a process for sharing end-to-end scenario based DSC configurations

https://blogs.msdn.microsoft.com/powershell/2017/04/28/dsc-configuration-sharing/

These are open to community involvement

Posted in DSC | Leave a comment

Mass dismount VHDs

I’m going to be creating, using and discarding a number of VHDs for my diskpart and PowerShell series. When I have a number of them mounted I want a quick way to dismount them. Assuming I consistently keep them in the same folder then this very nicely

Get-ChildItem -Path C:\test\ -Filter *.vhdx | Dismount-VHD

Why does it work?

Because Get-ChildItem emits System.IO.FileInfo objects that have a Path property and Dismount-VHD accepts pipeline input for the Path of the VHD to dismount:

-Path <String[]>
    Specifies one or more virtual hard disk files for which the corresponding virtual hard disks are to be dismounted.

    Required?                    true
    Position?                    1
    Default value                none
    Accept pipeline input?       true (ByValue, ByPropertyName)
    Accept wildcard characters?  false

Posted in Powershell, Storage | Leave a comment

Diskpart and PowerShell–part 3: Initialize disk and create volume

Last time we created a virtual disk and mounted it. In this post we’ll initialize the disk and create a volume.

Start by remounting the disk

Get-VHD -Path C:\test\Test1.vhdx | Mount-VHD

You can now initialize the disk:

Initialize-Disk -Number 1

Create a partition:

New-Partition -DiskNumber 1 -DriveLetter F –UseMaximumSize

Ignore the message about formatting as you want to control that:

Format-Volume -DriveLetter F -FileSystem NTFS -Confirm:$false –Force

Your new disk is ready to use.

The diskpart equivalents can be found here: https://technet.microsoft.com/en-us/library/cc766465(v=ws.10).aspx

You can perform the creation and formatting of the disk in one pass:

New-VHD -Path C:\test\Test2.vhdx -Dynamic -SizeBytes 10GB |
Mount-VHD -Passthru |
Initialize-Disk -PassThru |
New-Partition -DriveLetter G -UseMaximumSize |
Format-Volume -FileSystem NTFS -Confirm:$false –Force

Parameterize the path, size and drive letter and you have a handy function to set up disks

Posted in Powershell, Storage | Leave a comment