powershell

    “At this point, I’m pretty sure, that if I lost my .zsh_history I probably wouldn’t be able to do my job anymore. Most of the commands I run are really just CTRL+R plus minor edits.” [Shell History Is Your Best Productivity Tool - Martin Heinz] (https://martinheinz.dev/blog/110?utm_source=tldrnewsletter)

    Me too, although replacing .zsh_history with whatever’s in $(Get-PSReadLineOption).HistorySavePath

    How to continuously run a set of Pester tests from the commandline

    while ($(get-date).hour -lt 19) {invoke-pester .\tests-folder\*.tests.ps1 -output Normal 5>c:\temp\debug_output.txt }
    

    I imagine you can do this from within VS Code, but I sometimes have this running on a 2nd screen while I’m coding.

    How to set default parameters for other people's Powershell cmdlets

    Not exactly #TodayILearned because I vaguely remember learning that you can do this, but had never got around to doing so.

    This is how you can set a default parameter in Powershell. As far as I know, it works with any cmdlet. I’m using it here to set the default for Pester to show me all the results of all the tests….because I love seeing that sea of green :)

    $PSDefaultParameterValues += @{ 'Invoke-Pester:Output' = 'Detailed' }
    

    #Powershell

    I need to decide whether I’m going to use $SplatParams or $SplatParameters….and then get that tattoo-ed on the inside of my eyelids or something

    #Powershell

    #TodayILearned that one way of getting a list of data available from Microsoft Graph API is to type ‘graph.microsoft.com/v1.0/user… into Graph Explorer, and see what show’s up in the Dropdown

    the dropdown in Graph Explorer

    Vim commands to write out parameter list

    Executive summary :)

    For each line

    
    0
    
    D
    
    PP
    
    

    From the colon prompt:

    
    %s/^  */    write-dbg "`
    
    %s/  *\$/: <\$
    
    %s/$/>"
    
    %s/,//g
    
    

    The gory details

    Starting with a parameter clause like this:

    
    Param(
         $Parameter1,
         $Parameter2,
         $Parameter3,
         $Parameter4
    )
    

    The manual bits

    First, take off the ‘Param(i’, and the bracket at the end

    Second, for each line do this:

    0
    D
    PP
    

    … to get:

         $Parameter1,     $Parameter1,
         $Parameter2,     $Parameter2,
         $Parameter3,     $Parameter3,
         $Parameter4     $Parameter4
    

    The colon prompt bits

    Replace spaces at the front with the write-dbg, a double-quote, and then a backtick. The backtick is because I need to escape the name of the variable

    :%s/^  */    write-dbg "`
    

    This gives:

        write-dbg "`$Parameter1,     $Parameter1,
        write-dbg "`$Parameter2,     $Parameter2,
        write-dbg "`$Parameter3,     $Parameter3,
        write-dbg "`$Parameter4     $Parameter4
    
    

    Replace the spaces between the repeated variables with ‘: <’

    :%s/  *\$/: <\$
    
    

    ….giving:

        write-dbg "`$Parameter1,: <$Parameter1,
        write-dbg "`$Parameter2,: <$Parameter2,
        write-dbg "`$Parameter3,: <$Parameter3,
        write-dbg "`$Parameter4: <$Parameter4
    
    

    End the string:

    %s/$/>"
    

    ….which gives:

        write-dbg "`$Parameter1,: <$Parameter1,
        write-dbg "`$Parameter2,: <$Parameter2,
        write-dbg "`$Parameter3,: <$Parameter3,
        write-dbg "`$Parameter4: <$Parameter4
    
    

    Finally get rid of the commas

    %s/,//g
    
    
    

    Leaving:

        write-dbg "`$Parameter1: <$Parameter1>"
        write-dbg "`$Parameter2: <$Parameter2>"
        write-dbg "`$Parameter3: <$Parameter3>"
        write-dbg "`$Parameter4: <$Parameter4>"
    

    I’ve been told that, ergonomically, the top of your monitor should be level with your eyes.

    I’m sure this is good advice, but I’m wondering if it applies to people who live on the command line, because on the command line stuff tends to happen at the bottom of the screen #Powershell

    Screenshot of a screen which is largely empty, but with 'Hello' at the bottom of the screen

    How to post to a test micro.blog from powershell

    Sorry about the formatting of this post…I’m having trouble getting markdown not to convert the url to markdown links, even within code blocks

    There’s a bit more detail on posting generally from powershell at mattypenny.micro.blog/2024/02/1…

    This is the standard bit

    
    $Token = 'whatever-the-token-is' | ConvertTo-SecureString -AsPlainText -Force
    
    $Body = @{ content = 'Testing again. 1 , 2, 1, 2' h = 'entry' 'post-status' = 'draft' }
    
    

    You then put ‘?mp-destination=’ followed by the URL of the test micro.blog on the end of the base URL as in the gist below. (The markdown conversion is nausing up the URL if I type it in here - sorry!

    invoke-restmethod micro.blog/micropub -Method post -Authentication Bearer -Token $Token -Body $Body

    url preview edit


    mattypenny-test.micro.blog/2024/02/1… micro.blog/account/p… micro.blog/account/p…

    The output confirms that the post has gone to mattypenny-test.micro.blog

    Screen print of the command.

    How to post to micro.blog with powershell

    Get the token

    Go to the account page in micro.blog, scroll down to the bottom where there is ‘App tokens’ and click on the link which has the text ‘5 apps’ (or however many apps you’ve authorized)

    Screenprint of the link

    Pick an app name (I went wild with my imagination and called it Powershell), and click on ‘Generate Token’

    Screenprint of the App name box

    Reveal the token and Ctrl-C it.

    Do the powershell bit

    Convert the token into a securestring

    $Token = 'whatever-the-token-is' |  ConvertTo-SecureString -AsPlainText -Force
    

    Set up the $Body

    $Body = @{
      content = 'Testing again. 1 , 2, 1, 2'
      h = 'entry'
      'post-status' = 'draft'
    }
    

    You need the quotes around ‘post-status’ because Powershell doesn’t like hyphens in variable names. I’m keeping this post as draft, because the content is even less interesting than my other posts

    Then call invoke-restmethod as follows:

    invoke-restmethod https://micro.blog/micropub -Method post  -Authentication Bearer -Token $Token -Body $Body
    

    …and Bob’s your uncle

    Screen-print of the post

    There is, clearly, a lot more really basic stuff that I need to work out:

    • how to create a title

    • how to make the URL more meaningful (tbf, I don’t know how to do that through the browser as yet)

    • how to attach a photo

    • how to post to the testing blog rather than the default one

    Then, I’d like to:

    • create a function to select a particular post, download it, edit in in vim or vscode, then post the new version

    #TodayILearned that for #Powershell’s Get-ADUser, using -identity will return an error:

    $ $ErrorActionPreference = 'Stop'
    $ try {Get-AdUser -identity phineas.fogg} catch {"In catch"}
    In catch
    

    ….whereas using -filter won’t

    $ try {Get-AdUser -filter {samaccountname -eq 'phineas.fogg'}} catch {"In catch"}
    $
    

    My slightly late-in-the-day New Year’s Resolution is to use #Powershell’s Out-GridView more often and Format-Table less often

    Out-Gridview screen showing news about 'Pochettino'

    Function to return markdown link for a URL

    This function accepts a URL and returns a markdown link for the URL:

    
    function Get-MarkdownLinkForUrl {
    <#
    .SYNOPSIS
        Get the webpage, extract the title, and build a markdown link for the specified URL
    #>
        [CmdletBinding()]
        [OutputType([String])]
        param (
            [Parameter(Mandatory=$True)][string]$Url
        )
    
        $DebugPreference = $PSCmdlet.GetVariableValue('DebugPreference')
    
    
        $Webpage = invoke-webrequest $Url
        $Webpage.Content -match "<title>(?<title>.*)</title>" | out-null
        $Title = $matches['Title']
    
        "[$Title]($Url)"
    
    }
    set-alias gmd Get-MarkdownLinkForUrl
    
    

    It’s run as follows:

    
    Get-MarkdownLinkForUrl https://www.theguardian.com/football/2012/may/19/bayern-munich-chelsea-champions-league-final
    
    

    …which returns:

    
    [Chelsea win Champions League on penalties over Bayern Munich | Champions League 2011-12 | The Guardian](https://www.theguardian.com/football/2012/may/19/bayern-munich-chelsea-champions-league-final)
    
    

    which when rendered looks like this:

    Chelsea win Champions League on penalties over Bayern Munich | Champions League 2011-12 | The Guardian

    I can only ever remember git add, commit, diff, rm and push...and I couldn't be bothered to rtfm (Confessions of a powershell numpty, #1)

    I don’t use git much, and I’m far too lazy to consult the docco so to find a command I’d probably used before I did this:

    hhh git | where-object line -notmatch 'diff|add|push|commit| rm '
    

    ….where hhh is an alias to a crappy little function I wrote:

    function get-MTPSavePAthHistory {
        <#
        .SYNOPSIS
          Search through history
        #>
        [CmdletBinding()]
        Param ($Pattern = "*",
            $Tail = 50)
    
        [string]$HistoryFile = $(Get-PSReadLineOption).HistorySavePAth
        if ($Pattern -eq "*") {
            get-content -tail $Tail 
        }
        else {
            Select-string "$Pattern" $HistoryFile | select-object line
        }
    
    }
    Set-Alias -Name hhh -Value get-MTPSavePAthHistory
    

    What I really did

    It gets worse

    Because I am a numpty, and I couldn’t remember whether whether -notmatch would work in this context, what I really did was this:

    hhh git | ? line -notlike "*add*" | ? line -notlike "*diff*" | ? line -notlike "*commit*"| ? line -notlike "*push*"
    

    I did a one page ‘‘What is Powershell?’ slide

    I’m happy enough with it, but the penguin is probably too prominent. I was making the point that it’s comparable to Bash etc. I’m overfond of drawing the penguin tbh

    Sketchnote of What is Powershell

    I don’t use the ‘Close Others’ option enough in VS Code….and I end up with a couple of dozen tabs

    The Close Others option in VS Code

    #TodayILearned that to remove the two different timestamps I tend to use you can do this in Powershell

     # Strip YYMMDDHHMISS
    $ErrorText = $ErrorText -replace "_\d{12}", ""
    
     # Strip YYYYMMDDTHHMISSnnnn
    $ErrorText = $ErrorText -replace "_\d{8}T\d{10}", ""
    

    [IO.Directory]::EnumerateFiles vs. Get-ChildItem

    On my laptop, with a fairly random set of files, I found that

    [http://IO.Directory]::EnumerateFiles 
    

    ….is a lot quicker than

    get-childitem
    

    ….given that all I wanted was the filename.

    Here is the test I did:

    11:24 [1.83] C:\powershell >measure-command {$x = [IO.Directory]::EnumerateFiles("c:\temp", "*", 'AllDirectories')} | select milliseconds
    
    Milliseconds
    ------------
               4
    
    
    14:26 [0.02] C:\powershell >measure-command {$x = [IO.Directory]::EnumerateFiles("c:\temp", "*", 'AllDirectories')} | select milliseconds
    
    Milliseconds
    ------------
               2
    
    
    14:26 [0.01] C:\powershell >measure-command {$x = [IO.Directory]::EnumerateFiles("c:\temp", "*", 'AllDirectories')} | select milliseconds
    
    Milliseconds
    ------------
               2
    
    
    14:26 [0.01] C:\powershell >measure-command {$x = get-childitem -recurse "c:\temp"} | select milliseconds
    
    Milliseconds
    ------------
             137
    
    
    14:26 [1.14] C:\powershell >measure-command {$x = get-childitem -recurse "c:\temp"} | select milliseconds
    
    Milliseconds
    ------------
             731
    
    
    14:26 [0.74] C:\powershell >measure-command {$x = get-childitem -recurse "c:\temp"} | select milliseconds
    
    Milliseconds
    ------------
             628
    
    
    

    Why Powershell

    Sketchnote on the many virtues of Powershell

    Pester script parameter passing not working

    Problem

    I was trying to parameterize a Pester script. The script looked like this:

    param (
       [string]$ComputerName,
       [string]$IPAddress
    )
    
    write-dbg "$ComputerName: "
    write-dbg "$IPAddress: "
    
    Describe "$ComputerName is visible" {
    
        "It is ping-able" {
           {test-connection $ComputerName -count 1} | Should Not Throw
    
           $(test-connection $ComputerName -count 1 | Measure-Object).count | Should Be 1
        }
    
    }
    

    …but passing the parameters wasn’t working.

    Solution

    The problem was that I was calling the script as follows

    $ Invoke-Pester  @{PAth = c:\pester\diagnostics\simple\StandardDomainContoller.tests.ps1; Parameters=@{ComputerName = "server1.here.co.uk";IPAddress = "17.6.5.1""}}
    

    …and the Path variable needs quotes:

    $ Invoke-Pester  @{PAth = 'c:\pester\diagnostics\simple\StandardDomainContoller.tests.ps1'; Parameters=@{ComputerName = "server1.here.co.uk";IPAddress = "17.6.5.1""}}
    

    What I learned about powershell in 2017, according to my twitter archive

    Nov 24, 2017

    #TodayILearned that:

    $Content = get-content somefile.txt | out-string

    …preserves the line breaks in the text file

    via social.technet.microsoft.com/Forums/sc…

    Nov 21, 2017

    #TodayILearned

    set backupdir=C:\temp\vim set directory=C:\temp\vim

    via @hellojs_org at blog.hellojs.org/configure…

    Nov 8, 2017

    #TodayILearned that the batch command equivalent of the bash sleep is Timeout

    May 24, 2017

    #TodayILearned that you can replace a pattern in Powershell: “images\Leopold_I_of_Belgium 226x300” -replace “[0-9][0-9]x[0-9][0-9]”,""

    Mar 31, 2017

    #TodayILearned that if you put a ValidateSet on a #Powershell cmdlet parameter, then ISE Tab-completion will pick it up. Very handy!

    Mar 21, 2017

    #TodayILearned you can omit the Get- from Powershell commands…‘tho just because you can…doesnt mean you should!

    community.idera.com/powershel…

    Jan 20, 2017

    #TodayILearned that you can set a CSV in a here-string and turn it into an object.

    Handy for small test datasets in @PSPester

    Jan 3, 2017

    #TodayILearned that ‘show-command’ in Powershell creates a nice little GUI window for a function or cmdlet community.idera.com/powershel…

Older Posts →