Average Rating:

5.00 by 3 users.

43 Downloads, 141 Views

2 Comment(s)

Library-TempFile.ps1

By: Bartek Bielawski 17 Apr 2011 06:33 PM UTC in the category: Advanced Event 10

Description:

Script with single function to create temporary files from pipeline input. Need to dot-source it in order for it to work, thus name of the script. I tried to use all good things that come with advanced functions. I even managed (finally ;) ) to get proper support for 'Yes to All' and 'Now to All' in process block, usually it was asking regardless option selected... ;) I used -confirm:$false to prevent cmdlets from picking up $ConfirmPreference (they would prompt user again). Was not sure which verb too choose (Out or New) - finally decided to go with New, as we create things rather than redirect stuff to something that is always there (like Host... or Null ;) ).
function New-TempFile {

<#
    .SYNOPSIS
    
        Function to create temporary file from a contented piped into it.

    .DESCRIPTION
    
        This function will create temporary file for you from content you pipe to it.
        It has all features of advanced functions:
        * SupportsShouldProcess (-WhatIf, -Confirm, -Force, including Yes To All and No To All support
        * Lot of -Debug and -Verbose information
        * Comment based help - you are reading it ATM ;)
        * Validation of parameters
        * User-friendly pipeline support.
            
    .PARAMETER  WhatIf
    
        Display what would happen if you would run the function with given parameters.
    
    .PARAMETER  Confirm
    
        Prompts for confirmation for each operation. Allow user to specify Yes/No to all option to stop prompting.

    .EXAMPLE
    
        'alfa beta gamma delta'.Split() | New-TempFile
        Creates new temporary file from array of strings passed to the pipeline. Using default (Unicode) Encoding.
    
    .EXAMPLE
    
        'alfa beta gamma delta'.Split() | New-TempFile -Encoding ASCII -Verbose
        Creates new temporary file with same contents but with different encoding. It will display more information.

    .EXAMPLE
    
        Get-Process | Out-String -Stream | New-TempFile -Show
        Creates Get-Process output, converts it into strings, saves in temporary file and opens it using notepad.exe.

    .INPUTS
        
        System.String

    .OUTPUTS

        System.String
        
    .NOTES
        
        Author: Bartosz Bielawski
        Date created: 17-Apr-2011
        Last modified: 17-Apr-2011
        Version: 1.0
        Reason for last modification: complete help information

    .LINK
        
        Add-Content
    
    .LINK
    
        http://blogs.technet.com/b/heyscriptingguy/archive/2011/04/15/the-2011-scripting-games-advanced-event-10-use-powershell-to-create-a-function-to-create-temp-files.aspx

#>

[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
param (
    # Data that will be used to fill file with contents.
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true,
        HelpMessage = 'String that will be used to fill temporary file with contents')]
    [AllowEmptyString()]
    [string]$Value,
    
    # Switch to avoid any prompts about overwriting/ creating file.
    [Parameter()]
    [switch]$Force,
    
    # Encoding of newly create file. Valid values: String, Unicode, BigEndianUnicode, UTF8, UTF7, Ascii.
    # Default value: Unicode.
    [Parameter()]
    [ValidateSet("String", "Unicode", "BigEndianUnicode", "UTF8", "UTF7", "Ascii")]
    [string]$Encoding = 'Unicode',
    
    # Optional feature to open newly created temporary file in notepad.exe
    [Parameter()]
    [switch]$Show
)

begin {

    Set-StrictMode -Version Latest

    # Flag to keep information for next function part if we should continue with operation or not.
    # It's only purpose it's to workaround problem that 'return' statement is not getting out of whole function.

    $ShouldReturn = $False
    
    if ($DebugPreference -ne 'SilentlyContinue') {
        # We would like to see all -Verbose messages in -Debug view...
        $VerbosePreference = 'Continue'
    }
    
    if ($Show) {
        # User wanted to view file instantly, so let's add it to end block.
        Write-Debug "User want to view file after it is created."
        $EndBlock = {
            notepad $Path
            $Path
        }
    } else {
        Write-Debug "User do not want to view the file after it is created."
        $EndBlock = {
            $Path
        }
    }
    
    # Create a file, define it's path, name and so long, and so forth.

    $Path = [IO.Path]::GetTempFileName() + '.txt'
    Write-Debug "Path to newly created file: $Path"
    
    try {
        # Handle prompt
         
        if ($Force  -or $psCmdlet.ShouldProcess($Path,'Create new file to store data')) {
            New-Item -ItemType File -Path $Path -Confirm:$False | Write-Verbose
        } else {
            Write-Verbose "File not created, quit."
            $ShouldReturn = $True
            return
        }

    } catch {

        Write-Debug $_

    } finally {

        if (!(Test-Path -Path $Path -PathType Leaf)) {
            Write-Verbose "File not created, quit."
            $ShouldReturn = $True
            return
        }
        
        # Create hashtable that will be used for splatting.
        # To avoid doubled -Confirm prompt - set Confirm to $false
        # We do not need Add-Content to handle it, we will handle it.
        
        $Params = @{
            Path = $Path
            Encoding = $Encoding
            Confirm = $False
            Force = $Force
        }
        
        Write-Debug "Created hashtable that we will pass to Add-Content: $($Params | Out-String)"
        
        # Configure YesToAll Depending on $ConfirmPreference variable.
        # for -Confirm switch $ConfirmPreference will be set to Low.
        # Set NoToAll to $False always.
        
        if ($ConfirmPreference -eq 'Low') {
            Write-Debug "User asked for -Confirm, setting 'YesToAll' to $False"
            [bool]$YesToAll = $False
        } else {
            [bool]$YesToAll = $True
        }
        
        [bool]$NoToAll = $False
        
    } # END of finally
} # END of function New-TempFile begin block

process {
    
    # First check if there were no serious issues in begin block.
    
    if ($ShouldReturn) {
        Write-Debug "Skip process block - file not created in the begin block..."
        return
    }

    try {
        if ($Force -or $pscmdlet.ShouldContinue("Add content: $($Value.ToString()) `nTo file: $Path",
                'Confirm add content',
                [ref]$YesToAll,
                [ref]$NoToAll)) {

            $Params.Value = $Value
            Add-Content @Params
        }
    
    } catch {
    
        Write-Debug $_
    }
}

end {
    
    if ($ShouldReturn) {
        Write-Debug "Skip end block - file not created in the begin block..."
        return
    } else {
        & $EndBlock
    }
}
} # END of function New-TempFile
Top

Comments:

4/21/2011 11:08 PM
Excellent script. I love your parameters and comment based help
4/25/2011 11:03 AM
Great script. As for the verb of your function, I would rather go with 'out' as in 'out-file' which does not imply that the file is always there. 'out' seems the preferred verb when you capture your pipeline output in a single container (the host, a printer, a file, etc). 'new' is more focused on the specific task of creating an object, and most importantly 'new-*' commands can be - and are typically - used without any pipeline input.