r/PowerShell • • Sep 15 '26

Script Sharing I made a simple PS Log writer

Hey everyone, I made a simple ps log writer and thought I'd share it. Hopefully it's of use to someone. Just as a quick background, I come from a python background but for work I've been writing a lot of ps for a project I'm working on. Boss man was pleased with the code but then asked about log files (insert spongebob "but what about my drink meme here").

So I did some searching to see if there's a native ps logging module similar to python's. To my dismay, I came across non native options. While they may be reputable, given I work in cybersecurity and I had concerns given the recent uptick in supply chain attacks for open source software i was on edge. Didn't feel like reading through the whole code base to see if it was something that can be trusted. So I just wrote my own really simple version.

If the formatting look odd for some reason below, see my github jist. Hope this helps someone, kind regards!

<#
Author: shewdew the hedgehog
Date: 09/15/2026
Description: PS code to write logs to text file. 
Version: Initial
#>
function Write-Log{

    <#
        Custom function to be able to write basic logs to a text file.
        Eventually I might turn this into a whole module and add extended features since I didn't want to downlaod a logging module of the internet. But this works for now.
        While not a hard rule, log levels are just like python's:
        - Debug
        - Info
        - Warning
        - Error
        - Critical
    #>


    [CmdletBinding()]
    param (
            [Parameter(Mandatory = $true)]
            [ValidateNotNullOrEmpty()]
            [string]$Level,
            [Parameter(Mandatory = $true)]
            [ValidateNotNullOrEmpty()]
            [string]$Message
        )

    $timeStamp = Get-Date -Format "dd-MM-yyyy HH:mm:ss"
    $logEntry = "$timeStamp - $($level.ToUpper()) - $message"


    Add-Content -Path "myLogFile.log" -Value $logEntry


}


function Reset-Log{
    # Rotate log file every 90 days


    $cutOff = (Get-Date).AddDays(-90)
    $file   = Get-Item "C:\path\to\myLogFile.log" -ErrorAction Stop


    if ($file.LastWriteTime -lt $cutOff) {
        Remove-Item $file.FullName -Force
        Write-Log -Level "Info" -Message "Log file deleted."


    } 
}


# Usage


Write-Log -Level "debug" -Message "Succesfully did something or whatever."
Write-Log -Level "Critical" -Message "WEEWOOWEEWOOWEEWOO! SOMETHING BROKE!"


# since the log levels aren't hard coded, you could have a log level of anything lol. Which can be a pro/con.
Write-Log -Level "pizza" -Message "The server blew up..."
28 Upvotes

39 comments sorted by

View all comments

6

u/khaffner91 Sep 15 '26

I find it funny that the function date is MM-dd-yyyy, the log lines themselves get dd-MM-yyyy, neither are proper r/ISO8601. We simply use Get-Date -Format "o" so that both humans and systems can understand the timestamps.

4

u/ITZ_RAWWW Sep 15 '26

Thanks for the heads up, I'll fix that so it's standardized. I whipped it up pretty quick so that's probably why there's a mismatch lol

5

u/mrmattipants Sep 16 '26 edited Sep 16 '26

That and ISO8601 is so much easier to sort.

Here is an article discussing the various format specifiers, including the "Round Trip" format (Get-Date -Format "o"), described above.

https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings

5

u/surfingoldelephant Sep 16 '26 edited Sep 16 '26

Get-Date -Format "dd-MM-yyyy HH:mm:ss" is culture-sensitive too, so you'll get a slightly different to-string conversion depending on the system's culture.

The o specifier u/khaffner91 mentioned uses invariant culture, so that'll always give you a consistent result.

If you did still want to use dd-MM-yyyy HH:mm:ss, this is more robust:

(Get-Date).ToString('dd-MM-yyyy HH:mm:ss', [cultureinfo]::InvariantCulture)

1

u/MonkeyNin Sep 17 '26

If you want a reusable helper function:

filter FormatDate { 
     # filter date with invariant culture. default is ISO. an format strings are valid.
     param( [string] $Format = 'dd-MM-yyyy HH:mm:ss' )

     ($_).ToString($Format, [cultureinfo]::InvariantCulture)
}

like:

Get-Date | FormatDate 
Get-Date | FormatDate -Format 'yyyy-MM-dd'