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:
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
.