Export pipeline output to a MarkDown file using PowerShell

I like using MarkDown to format text and Obsidian to save my notes, and sometimes you want to export the output from cmdlets or scripts for future reference. This blog post will show you how to easily save that output to a new or existing MarkDown file.

What is MarkDown?

“Markdown is a lightweight markup language that you can use to add formatting elements to plaintext text documents. Created by John Gruber in 2004, Markdown is now one of the world’s most popular markup languages.” For more information, you can check out this Getting Started link.

How the script works

The Out-MarkDown function accepts data from the pipeline and exports that to the specified md file. It will always append the data to it, but you can use the -Overwrite switch to overwrite any existing file. The contents it receives from the pipeline will be inserted into a code block of a new Heading with a horizontal line at the start and end. It will also start with a date and time value of when the data was inserted into the MarkDown file.

Running the script

In the example below, I run the command to show me the Names and last write times of all the JSON files in d:\temp and output that information to c:\data\PowerShellisfun.md where I overwrite any existing earlier version of that file:

PS D:\Data\GitHub\PowerShell\PowerShellisfun scripts> Get-ChildItem d:\temp\*.json | Select-Object Name, LastWriteTime | Out-MarkDown -OutputFile C:\data\PowerShellisfun.md -Overwrite
Overwriting existing file C:\data\PowerShellisfun.md
Saving pipeline input to file C:\data\PowerShellisfun.md
Done, exported data to C:\data\PowerShellisfun.md

This will result in a MarkDown file that looks like this in Obsidian (Or any other MarkDown viewer/tool)

The script

You can save the contents of the script below to c:\scripts\Out-MarkDown.ps1 and make it available in your PowerShell sessions by running:

notepad $profile
Add ". c:\scripts\Out-MarkDown.ps1"
Quit/Save
Start a new PowerShell Session

If you always want to save the output of a cmdlet or script to the same file or if you always want to overwrite any existing files, you can change the two lines at the beginning of the script to specify just that. (Lines 11 and 14)

Function Out-MarkDown {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]$InputObject,
        [parameter(Mandatory = $false, Position = 1)][string]$OutputFile,
        [switch]$Overwrite
    )

    Begin {
        #Remove the # below and configure the default location for the outputfile
        #$outputfile = 'c:\Data\powershellisfun.md'

        #Remove the # below and configure the default to overwrite the existing file
        #$overwrite = $true
        
        #Exit if $outputfile was not configured or used
        if (-not $OutputFile) {
            Write-Warning ("The -Outputfile parameter was not used, or the outputfile variable was not set at the top of the script. Exiting...")
            break
        }
                
        #Validate write access to specified $OutputFile location if Overwrite switch was used
        if ((Test-Path -Path $OutputFile) -and $Overwrite) {
            try {
                New-Item -Path $OutputFile -ItemType File -force:$Overwrite -ErrorAction Stop | Out-Null
                Write-Host ("Overwriting existing file {0}" -f $OutputFile) -ForegroundColor Green
            }
            catch {
                Write-Warning ("Couldn't overwrite {0}, please check path/permissions or if the file is locked. Exiting..." -f $OutputFile)
                break
            }
        }

        #Validate if $outputfile is an existing file or a new file, and if the Overwrite switch was not used
        if ((Test-Path -Path $OutputFile) -and -not $Overwrite) {
            Write-Host ("Appending pipeline input to existing file {0}" -f $OutputFile) -ForegroundColor Green
        }
        else {
            Write-Host ("Saving pipeline input to file {0}" -f $OutputFile) -ForegroundColor Green
        }

        #Set codeblock back-ticks in $codeblock, an empty line in $emptyline and horizontal line in $horizontalline variable
        $codeblock = "``````"
        $emptyline = ""
        $horizontalline = "___"

        #Add time-stamp header to outputfile and the data from Pipeline in a codeblock
        ("{0}" -f $emptyline) | Out-File -FilePath $OutputFile -Encoding utf8 -Append -Width 1024
        ("{0}" -f $horizontalline) | Out-File -FilePath $OutputFile -Encoding utf8 -Append -Width 1024
        ("# Data added using Out-MarkDown.ps1 on {0}" -f $(Get-Date -Format "dd-MM-yyyy HH:mm:ss")) | Out-File -FilePath $OutputFile -Encoding utf8 -Append -Width 1024
        ("{0}" -f $codeblock) | Out-File -FilePath $OutputFile -Encoding utf8 -Append -Width 1024

    }

    Process {
        $InputObject | Out-File -FilePath $OutputFile -Append -Encoding utf8 -Width 1024
    }

    End {
        #Add end of codeblock to file and exit
        ("{0}" -f $codeblock) | Out-File -FilePath $OutputFile -Encoding utf8 -Append -Width 1024
        ("{0}" -f $horizontalline) | Out-File -FilePath $OutputFile -Encoding utf8 -Append -Width 1024
        ("{0}" -f $emptyline) | Out-File -FilePath $OutputFile -Encoding utf8 -Append -Width 1024
        Write-Host ("Done, exported data to {0}" -f $OutputFile) -ForegroundColor Green
    }
}

Download the script(s) from GitHub here

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.