Recommendations for writing custom scripts

Most cmdlets and scripts return information efficiently without any special handling or any noticeable effect on performance. If you plan to write custom scripts that could potentially return large data sets, however, you should consider ways to improve performance. For example, if you are writing a script that exports a large number of sessions or reports on activity for a large audit installation, you might want to use the following recommendations as guidelines.

  • When testing the performance of the script, use the standard Measure-Command cmdlet to accurately measure cmdlet and script performance.

    The Measure-Command cmdlet ignores the time it takes to print all of the results returned to the PowerShell console. In many cases, the execution of a query or script is efficient, but rendering the results in the PowerShell console might make the cmdlet or script performance seem unacceptable.

  • Avoid using the PowerShell pipeline if your cmdlet or script returns large data collections.

    For example, you might use foreach in a script instead of using the pipeline to improve performance.

    Use syntax similar to this:

    foreach ($cmd in Get-CdaUnixCommand -Session $s) { action_on_each_cmd }

    Instead of:

    Get-CdaUnixCommand -Session $s | action_on_each_cmd
  • Cache the data, if possible, by writing the results to a file.

    For example, use syntax similar to this:

    $cmds = Get-CdaUnixCommand -Session $s
    Out-File -InputObject $cmds -FilePath file

    Instead of:

    Get-CdaUnixCommand -Session $s | Out-File -FilePath file
  • Use Export-Csv instead of Out-File if possible. The Export-Csv cmdlet writes results to a file faster than the Out-File cmdlet.

  • If you are writing a script that generates a very large data set—for example, reporting information for a global audit installation—you might want to use the native .NET FileStream function. The FileStream function is the fastest way to write content to a file.

    For example, you might use a code snipper like this:

    $fs = New-Object IO.FileStream <file>, 'Append','Write','Read'
    	$fw = New-Object System.IO.StreamWriter $fs
    	      $cmds = Get-CdaUnixCommand -Session $s
    	      foreach ($cmd in $cmds) {$fw.WriteLine("{0} {1} {2}", 
                      $cmd.Sequence, $cmd.Time, $cmd.Command)}
    	$fw.Close()
    $fs.Dispose()