0

I am trying to write a migration/deployment script to deploy an application to an environment (DEV, QA, PROD) and I need to be able to fully log all output. This would include any status message I specifically put in the output stream (not a problem) as well as verbose output from all commands. For instance, if I'm calling Copy-Item, I want the full listing of each item copied.

I'm trying to figure out a way to do this throughout the entire script reliably. In other words, I don't want to rely on including -Verbose on every command (as it could be missed when someone else maintains the script in the future). I've been looking at things like $VerbosePreference as well as the possibility of calling my main cmdlet/function using -Verbose, with the hope being that either would apply to the entire script. But that appears to not be the case. While any Write-Verbose commands I use respect either approach, calls to Copy-Item only show the verbose listing if I specifically pass -Verbose to it. I'm really hoping I'm just missing something! Surely this is possible to do what I'm wanting!

Sample code:

function Main () {
    [CmdletBinding()]
    Param()

    Begin {
        Copy-Item C:\Temp\src\* -Destination C:\Temp\dest -Recurse -Force
        Write-Output 'Main output'
        Write-Verbose 'Main verbose'
        Child
    }
}
function Child () {
    [CmdletBinding()]
    Param()

    Begin {
        Copy-Item C:\Temp\src\* -Destination C:\Temp\dest -Recurse -Force
        Write-Output 'Child output'
        Write-Verbose 'Child verbose'
    }
}

$VerbosePreference = 'SilentlyContinue'
Write-Output $VerbosePreference
Main
''
Main -Verbose

''
''
$VerbosePreference = 'Continue'
Write-Output $VerbosePreference
Main
''
Main -Verbose

Produces output:

SilentlyContinue
Main output
Child output

Main output
VERBOSE: Main verbose
Child output
VERBOSE: Child verbose


Continue
Main output
VERBOSE: Main verbose
Child output
VERBOSE: Child verbose

Main output
VERBOSE: Main verbose
Child output
VERBOSE: Child verbose

So, clearly $VerbosePreference and -Verbose are affecting the Write-Verbose, but that's about it. The Copy-Item is not displaying ANY output whatsoever (though it will if I specifically use -Verbose directly on that command).

Any thoughts? Am I going about this all wrong? Please help!

glancep
  • 356
  • 5
  • 18

1 Answers1

3

How about leveraging...

Tip: Create a Transcript of What You Do in Windows PowerShell

The PowerShell console includes a transcript feature to help you record all your activities at the prompt. As of this writing, you cannot use this feature in the PowerShell application. Commands you use with transcripts include the following:

https://technet.microsoft.com/en-us/library/ff687007.aspx

... or the approaches provided / detailed here:

Enhanced Script Logging module (automatic console output captured to file)

Automatically copy PowerShell console output to a log file (from Output, Error, Warning, Verbose and Debug streams), while still displaying the output at the console. Log file output is prepended with date/time and an indicator of which stream originated the line

https://gallery.technet.microsoft.com/scriptcenter/Enhanced-Script-Logging-27615f85

Write-Log PowerShell Logging Function

The Write-Log PowerShell advanced function is designed to be a simple logger function for other cmdlets, advanced functions, and scripts. Often when running scripts one needs to keep a log of what happened and when. The Write-Log accepts a string and a path to a log file and ap

https://gallery.technet.microsoft.com/scriptcenter/Write-Log-PowerShell-999c32d0

* Update as per the OP comment*

See this discussion...

Powershell apply verbosity at a global level

where the -verbose flag is not supplied to the ni command. Is there a way to set the Verbosity at a global PSSession level if I were to run this script to force verbosity? The reason I ask is that I have a group of about 60 scripts which are interdependent and none of these supply -verbose to any commands they issue and I'd like to see the entire output when I call the main entry point powershell script.

Powershell apply verbosity at a global level

Use PowerShell Default Parameter Values to Simplify Scripts

Changing default parameter values

When I was asked to write about my favorite Windows PowerShell 3.0 feature, my #1 $PSDefaultParameterValues came to mind immediately. From my point of view, this was something I was looking for, for a long time.

How does it work? With $PSDefaultParameterValues, you can define (overwrite) default values of parameters for Windows PowerShell cmdlets.

https://blogs.technet.microsoft.com/heyscriptingguy/2012/12/03/use-powershell-default-parameter-values-to-simplify-scripts/

See also:

Script Tracing and Logging

While Windows PowerShell already has the LogPipelineExecutionDetails Group Policy setting to log the invocation of cmdlets, PowerShell’s scripting language has plenty of features that you might want to log and/or audit. The new Detailed Script Tracing feature lets you enable detailed tracking and analysis of Windows PowerShell scripting use on a system. After you enable detailed script tracing, Windows PowerShell logs all script blocks to the ETW event log, Microsoft-Windows-PowerShell/Operational. If a script block creates another script block (for example, a script that calls the Invoke-Expression cmdlet on a string), that resulting script block is logged as well.

Logging of these events can be enabled through the Turn on PowerShell Script Block Logging Group Policy setting (in Administrative Templates -> Windows Components -> Windows PowerShell).

https://learn.microsoft.com/en-us/powershell/wmf/5.0/audit_script

postanote
  • 15,138
  • 2
  • 14
  • 25
  • Appreciate the quick response, but I don't see how any of these options would force all cmdlets to use verbose output? I reviewed all three, and tried out Enhanced Script Logging, but still had to manually add `-Verbose` to the end of my `Copy-Item` command to get item listing logged. – glancep Mar 16 '18 at 19:09
  • No worries, but you set the verbosity at the global level. See the added update for you. – postanote Mar 16 '18 at 19:55
  • Perfect! `$PSDefaultParameterValues['*:Verbose'] = $true` worked exactly as I needed. Thanks! – glancep Mar 19 '18 at 13:21