---
title: "Write-Log: Creating a Custom PowerShell Logging Function"
description: "Streamline your logging process with a custom Write-Log PowerShell function. Make your logs more insightful."
canonical: "https://adamtheautomator.com/powershell-log-function/"
---

# Write-Log: Creating a Custom PowerShell Logging Function

> Streamline your logging process with a custom Write-Log PowerShell function. Make your logs more insightful.

Source: https://adamtheautomator.com/powershell-log-function/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![Write-Log: Creating a Custom PowerShell Logging Function](https://adamtheautomator.com/wp-content/uploads/2019/06/5d238ae5c824b514689ea56a.jpg)

# Write-Log: Creating a Custom PowerShell Logging Function

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)28 June 20192 min. read

Categories: [IT Ops](/category/it-ops/)

Tags:[Logging](/tag/logging/)[PowerShell](/tag/powershell/)

Table of Contents

*   [Define What You Need to Log](#h-define-what-you-need-to-log)
*   [Build the PowerShell Log Function Scaffold](#h-build-the-powershell-log-function-scaffold)
*   [Adding Output to the PowerShell Log Function](#h-adding-output-to-the-function)

Keeping tabs on what a script is doing is critical for monitoring and debugging. If you’re writing a PowerShell script, you need a go-to PowerShell log function you can use in all of your scripts.

If a script is invoked interactively, meaning directly from the console using techniques such as `Write-Verbose`, `Write-Information` or [`Write-Host`](https://adamtheautomator.com/powershell-write-host/ "Write-Host"), it is useful because each command can display messages on the console as the script runs.

But what if this script is getting invoked by a scheduled task or some other process that doesn’t involve a human staring at a screen while it runs? In this case, we’ll need to incorporate [another level of monitoring.](https://www.whatsupgold.com/log-management) An excellent way to monitor a script that doesn’t run interactively is by writing to a log file.

## Define What You Need to Log

There are a few different ways to write text to a text file in PowerShell, and the approach that’s used is completely up to the developer. However, before embarking on creating your own PowerShell log function, there are a few things to keep in mind.

*   All log lines need to be structured content. No loosey-goosey text messages strewed about.
*   The time should be recorded for each log entry.
*   A severity is recommended or other “tags” to quickly filter information in the log file later.

**_Related: [Set-Content: The PowerShell Way to Write to a File](https://adamtheautomator.com/powershell-write-to-file/)_**

## Build the PowerShell Log Function Scaffold

Let’s see how we can build a [PowerShell function](https://adamtheautomator.com/powershell-functions/ "PowerShell function") to incorporate into any of our scripts. Because this function will need to be available to several different scripts, we’re going to create a PS1 script just to store our function. The function’s name will be `Write-Log`.

```powershell
function Write-Log {
     [CmdletBinding()]
     param()
 
 }
```

This PowerShell log function will write a single log line every time it’s called. Each line in the log is going to have two attributes that will change depending on what I’d like to record; message and severity, so I will add those as parameters to our function.

```powershell
function Write-Log {
    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$Message,
 
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Information','Warning','Error')]
        [string]$Severity = 'Information'
    )
 
 }
```

Notice that I’ve chosen to limit the value of the `Severity` parameter to three choices. By limiting the options, it ensures that I can rely on this field to __always__ be one of three different severities. Once I’ve got the parameters built out, I’ll use CSV to create a structured log file. This will ensure that I can quickly pull up the log file in a spreadsheet program and look through the data, if necessary.

## Adding Output to the PowerShell Log Function

Notice below that I’ve also added the time to the PowerShell log function. This isn’t a parameter because this will always be the time the function was executed.

```powershell
function Write-Log {
    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$Message,
 
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Information','Warning','Error')]
        [string]$Severity = 'Information'
    )
 
    [pscustomobject]@{
        Time = (Get-Date -f g)
        Message = $Message
        Severity = $Severity
    } | Export-Csv -Path "$env:Temp\LogFile.csv" -Append -NoTypeInformation
 }
```

That’s all there is to our `Write-Log` function. We can now add this to any script we like as long as we dot-source it in first. If the _Write-Log.ps1_ script was in the same folder as the script we’re calling it from; we could dot-source it like `$PSScriptRoot\Write-Log.ps1`.

Once the script knows about the function, it can then be called as many times as necessary in a script.

```powershell
$foo = $false
if ($foo) {
    Write-Log -Message 'Foo was $true' -Severity Information
} else {
    Write-Log -Message 'Foo was $false' -Severity Error
}
```

The information would then get recorded to the log file which would look like this:

```powershell
$foo = $false
if ($foo) {
    Write-Log -Message 'Foo was $true' -Severity Information
} else {
    Write-Log -Message 'Foo was $false' -Severity Error
}
```

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-log-function%2F&text=Write-Log%3A%20Creating%20a%20Custom%20PowerShell%20Logging%20Function)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-log-function%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-log-function%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2026/06/26995-troubleshoot-dns-issues-powershell-codex.webp)

### [Troubleshoot DNS Issues with PowerShell](/troubleshoot-dns-issues-powershell/)

Troubleshoot DNS issues with PowerShell by testing name resolution, DNS client settings, cache entries, and network connectivity in a repeatable workflow.

![](https://adamtheautomator.com/wp-content/uploads/2025/10/image_2025-10-24_095322075.png)

### [Migrating from PowerShell 6 to 7.5: Breaking Changes/New Features](/migrating-powershell-6-to-7-5/)

Migrate from PowerShell Core 6 to 7.5: breaking changes, features, and testing tips.

![](https://adamtheautomator.com/wp-content/uploads/2025/06/featured-image-6.png)

### [How to Add Timeouts to Pester Tests with PowerShell Runspaces](/pester-test-timeout-runspaces/)

Prevent Pester tests from hanging indefinitely using PowerShell runspaces. Learn to handle variable scoping, module loading, TestDrive access, and stream capture challenges with timeout protection.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
