How to Create and Write to a File in PowerShell

Problem

As engineer, sometimes we need to automate writing to a file such as textfile. To achieve this task, we can use PowerShell.

In this blog post, we will walk you through how to create and write to a file in PowerShell.

Solution

All solutions below will be based on C# .NET Framework so the code will be equivalent with this C# code where it will create and write text to a file if the file does not exists.


internal class Program
{
    static void Main(string[] args)
    {
        string path = @"c:\temp\MyTest.txt";
        if (!File.Exists(path))
        {
            // Create a file to write to.
            using (StreamWriter sw = File.CreateText(path))
            {
                sw.WriteLine("Hello World!");
                sw.WriteLine("Welcome to PowerShell");
            }
        }
    }
}

The created file will look as follows:

result of create and write a file using powershell

Using Classes from .NET Framework Namespaces

Since PowerShell has access to .NET Framework libraries and classes, we can use some classes like File, StreamWriter, etc. from System.IO namespace to create and write a file.

In the following example, we create a textfile using CreateText static method that will return StreamWriter object. Based on this object, we will write some texts to the file.

Beforehand, we check whether the file exists or not using Exists static method.


using namespace System.IO

$path = "C:\temp\MyTest.txt";
if (![File]::Exists($path)) {

    try {
        $sw = [File]::CreateText($path)

        $sw.WriteLine("Hello World!");
        $sw.WriteLine("Welcome to PowerShell");    
    }
    finally {
        <#Do this after the try block regardless of whether an exception occurred or not#>
        $sw.Dispose();
    }
}

To work with File in .NET, we have to apply dispose pattern that can be achieved through try-finally block or using statement.

Since naturally PowerShell cannot use the latter option, we will use only the former option where Dispose method will be invoked in finally block to release the resource.

We have to do this because finally block must be executed whether the exception/error occurs during creating or writing a file in try block. So, we can ensure that the resource must be released.

If we don’t apply dispose pattern, memory leak will occur where eventually we will get OutOfMemoryException.

Emulate C# Using Statement

We know from previous example that PowerShell doesn’t have C# using statement that will ensure the object is disposed if exception occurs within using statement block.

However, we can create a function to emulate C# using statement by utilizing PowerShell script block. The function can be declared separately so that it can be imported in other files to make it modular or declared within the same file with the script that will use it.

In the following example, the function name is Use-Object. To use it, we enclose StreamWriter object inside Use-Object and any other statements to write a file inside curly brackets {}. If exception occurs, the object will be automatically released/disposed by finally block inside Use-Object function.


using namespace System.IO

function Use-Object {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [AllowEmptyString()]
        [AllowEmptyCollection()]
        [AllowNull()]
        [Object]
        $InputObject,

        [Parameter(Mandatory = $true)]
        [scriptblock]
        $ScriptBlock
    )

    try {
        . $ScriptBlock
    }
    finally {
        if ($null -ne $InputObject -and $InputObject -is [System.IDisposable]) {
            $InputObject.Dispose()
        }
    }
}

$path = "C:\temp\MyTest.txt";
if (![File]::Exists($path)) {

    Use-Object ($sw = [File]::CreateText($path)) {
        $sw.WriteLine("Hello World!");
        $sw.WriteLine("Welcome to PowerShell");
    }
}

Conclusion

One important point in this article is that we can utilize .NET Framework to do file processing in PowerShell. For creating and writing file we can use some classes from System.IO namespace.

We must also remember to implement dispose pattern when working with File processing in .NET Framework to avoid memory leak. Alternatively, we can emulate C# using statement that will automatically dispose the object by using PowerShell script block.

comments powered by Disqus