Initialize a Byte Array in PowerShell

Sometimes you’ll need to initialize a new buffer as an array of bytes. For example, if you want to generate random data using the NextBytes() method on the System.Random class,  you need to pass in a byte array buffer for the method to write to. Creating a byte array in PowerShell may not be immediately obvious. However, I found an answer on StackOverflow, that works in PowerShell Core on MacOS.

Let’s step through a quick example of how to create a buffer, and write it to a file on the filesystem.

Create an In-Memory Buffer (2KB)

The first thing you need to do is create the in-memory buffer, specifying the size (in bytes).

$BufferSize = 2048
$MyBuffer = [System.Byte[]]::new($BufferSize)

Fill Buffer with Random Data

Once you’ve initialized the byte array, you can generate some random data to fill the buffer.

$Random = [System.Random]::new()
$Random.NextBytes($MyBuffer)

Write In-Memory Buffer to Filesystem

Having generated 2 kilobytes of random data in-memory, you can write the buffered data to a new file.

$FilePath = '{0}/testfile-randomdata.txt' -f $HOME
$FileStream = [System.IO.File]::OpenWrite($FilePath)
$FileStream.Write($MyBuffer, 0, $MyBuffer.Length)
$FileStream.Close()

Append More Bytes to a File

If you want to append more random bytes to the file, simply refresh the buffer with new data by calling the NextBytes() method again, open the file for writing again, but this time, set the stream pointer to the end of the file (the last byte), and then call the Write() method on the FileStream again.

$Random.NextBytes($MyBuffer)
$FileStream = [System.IO.File]::OpenWrite($FilePath)

# Set the stream pointer to the end of the stream
$FileStream.Position = $FileStream.Length

# Write the newly generated buffer
$FileStream.Write($MyBuffer, 0, $MyBuffer.Length)

# Close out the file stream
$FileStream.Close()

New-RandomFile Function

Here’s a function I wrote up that will generate a random file of a specified size. You can also specify the -BufferSize parameter, which may affect performance depending on your hardware and partition configuration.

function New-RandomFile {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false)]
        [int] $Size = 1mb,
        [Parameter(Mandatory = $false)]
        [string] $Path = ('{0}/{1}' -f $HOME, (New-Guid).Guid),
        [Parameter(Mandatory = $false)]
        [int] $BufferSize = 4096
    )
    begin {
        $MyBuffer = [System.Byte[]]::new($BufferSize)
        $Random = [System.Random]::new()
        $FileStream = [System.IO.File]::OpenWrite($Path)
        $TotalSize = $FileStream.Length
        $FileStream.Position = $FileStream.Length
        Write-Verbose -Message ('File current size is: {0}' -f $FileStream.Length)
    }

    process {
        while ($TotalSize -lt $Size) {
            $Random.NextBytes($MyBuffer)
            $FileStream.Write($MyBuffer, 0, $MyBuffer.Length)
            $TotalSize += $BufferSize
            Write-Verbose -Message ('Appended {0} bytes to file {1}' -f $BufferSize, $Path)
        }
    }
    
    end {
        $FileStream.Close()
        [PSCustomObject]@{
            Path = $Path
        }
    }
}