powershell

    How to post to a test instance of micro.blog with powershell

    Source the micro.blog token

    $BlogToken =  $(import-csv /stuff/GeneralParameters.csv | ? parameter -eq 'BlogToken').value
    
    
    $headers = @{
      "Authorization" = "Bearer $BlogToken"
    }
    

    Get details for the micro.blog

    $response = Invoke-RestMethod -Uri "https://micro.blog/micropub?q=config" -Headers $headers
    

    This is the bit to get the uid of the test blog - mine is a fairly simple variation on the name of the main blog…as below. The URLEncode returns ‘https%3a%2f%2fmattypenny-test.micro.blog%2f’

    $response | select -ExpandProperty destination
    $MpDestination = [System.Web.HttpUtility]::UrlEncode("https://mattypenny-test.micro.blog/")
    

    build the Uri to upload to

    $mediaEndpoint = $response."media-endpoint"
    $Uri ="${mediaEndpoint}?mp-destination=$MpDestination" 
    

    Identify the file to upload

    $form = @{                                 
      file = Get-Item '/home/matty/working/spotify/images/Bethany Eve - Emerald City.png'
    }
    

    Upload it

    Invoke-RestMethod -Uri $Uri  -Method Post -Headers $headers -Form $form 
    

    And….hey presto

    Auto-generated description: A geometric mandala design featuring green and black shapes surrounds the text Emerald City at the center.

    Powershelling my twitter archive

    I’ve been looking at my twitter archive, with a view to importing bits of it into micro.blog (the automatic import didn’t quite work…I’m blaming Musk!)

    I’m using PowerShell

    Anyway so far I’ve learnt two things

    You have to take this bit out of the first line of the tweets.js file for convertfrom-json to work:

    window.YTD.tweets.part0 = 
    
    

    Some tweets seem to be truncated with a special character that looks like three dots….but this seems to mainly but not exclusively be retweets and the display url

          "created_at" : "Sun Apr 16 12:55:38 +0000 2017",
          "favorited" : false,
          "full_text" : "RT @SkrMkrSean: I'm at Ashton United v Blyth Spartans and all the Blyth are dressed as Mexicans holding up a wall banner behind a guy in a…",
    

    I linux-ified my aging windows laptop over the weekend

    All good, in general, and I’ll be able to get another couple of years out of it

    I found that:

    • I had to run the installer twice before it worked

    • gpodder picked up all my subscriptions from gpodder.net, which was handy, because I’d forgotten to export the opml

    • I had to log out and back in again to get gpodder to save to the folder I specified

    • Spotify seems identical. I use custom order, which I wasn’t expecting to be there in the Linux version….I’m wondering whether it’s actually the windows version running under wine

    • it’s a shame PSClock won’t run

    • I installed the Mate desktop…I very much prefer that to the default Ubuntu one

    • I haven’t got gvim set up yet

    • or VS Code

    • or any powershell stuff beyond installing it

    ……but it’s all good

    Ubuntu mate wall paper with a new Brighton lighthouse apparently

    “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
    
    
    
Older Posts →