Average Rating:

3.00 by 2 users.

30 Downloads, 93 Views


By: Eddy Steenbergen 21 Apr 2011 04:21 PM UTC in the category: Advanced Event 10


A bit like rewriting [IO.Path]::GetTempFileName() in powershell !?
# 2011 Scripting Games Advanced Event 10: Write advanced function to create temporary files
# Author: Eddy Steenbergen
# Due Date 22 Apr 2011 12:15 AM
# Version 3.

Function Out-TempFile 
          Accepts input from the pipeline in a string, stores it in a temporary text file and
          opens that file in Notepad (if requested). It outputs a string with the full name of the output file.
          This function accepts data via the pipeline. It normally expects string objects
          but if it finds a non-string it will convert it into a string.
          I had written an initial version of this function some time ago in which
          the temporary file is created using the .net method [IO.Path]::GetTempFileName().
          In this version I needed to develop an algorithm for naming the temporary file.
     .PARAMETER notepad
           Optional switch parameter. If present then the temporary file will be
           opened in Notepad for the user's viewing pleasure (or not).
           already exists.
     .PARAMETER showprogress
           Optional switch parameter. If present then shows progress bar.
     .PARAMETER encoding
           Optional string parameter. Allows the user to choose encoding for the 
           temporary file, defaults to ascii but allows unicode as an alternative.
          To process the file containing this function with debug:
            gc $MyInvocation.MyCommand.Path | Out-TempFile -showprogress -notepad -debug
          To view full help for this function:
            get-help Out-TempFile -full | out-string | Out-TempFile -showprogress -notepad
            $Encoding = "ascii"
        # calculate name for temporary file
        # try 40 random combinations of letters and digits until one is created
        [psobject[]] $letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" -split ""
        for($i=1;$i -lt 40;$i++) {
            $candidate = $env:username + "_" + ((get-random -inputobject $letters -count 10) -join "") + ".tmp"
            $pscmdlet.writedebug("attempt $i for file name:$candidate")
            if (new-item -path $env:temp -name $candidate -type file) {
                $tempfilepath = "$($env:temp)`\$candidate"
                $pscmdlet.writedebug("successful attempt $i for file name:$candidate")
                $tempfilemade = $true
        if (-not ($tempfilemade)) { $pscmdlet.ThrowTerminatingError("Unable to generate name for temporary file - very very very unlucky") }
        if ($showprogress) { $line = 0 }
        if ($showprogress) {
            $progressrecord = new-object System.Management.Automation.ProgressRecord(1,"Outputting data to temp file...","line $line")
            $pscmdlet.writedebug("Output line $line of data to temp file...")
        out-file $tempfilepath -inputobject $value.tostring() -append -encoding $Encoding
    END {
        $pscmdlet.writedebug("Output $line lines of data to temp file...")
		if ($notepad) {
            notepad $tempfilepath
            $pscmdlet.writedebug("Opened temp file in Notepad...")

# test on the source file for this script
gc $MyInvocation.MyCommand.Path | Out-TempFile -showprogress -notepad

# and the help for the function
get-help Out-TempFile -full | out-string | Out-TempFile -showprogress -notepad

# and on a collection of hashtables just for fun
(@{a="aa"},@{f="gg"}) | Out-TempFile -showprogress -notepad -debug