Hello all,
I have a large function that is used to scan permissions on Windows folders in large volumes. This function generates lots of verbose and debug messages, which I output to a Log File using the Start-Transcript/Stop-Transcript functions. The script also outputs some results via custom psobjects. All good so far.
My issue comes in when this function is run against very large Windows server volumes (i.e. 800,000+ folders). This of course generates an extremely large amount of verbose/debug messages to the console, which as it runs causes server memory utilization to increase and script speed to decrease.
What I am trying to do is find a way to simultaneously redirect my verbose/debug messages (Streams 4 and 5) to a log file, my results (Stream 1) to a Results file, all while suppressing any output to the console.
Here is a test script I put together to demonstrate what I’ve tried (the Start/Stop-Transcript method and the “redirection” method), all to no avail.
function Output-Message {
[CmdletBinding()]
param(
[string]$Message
)
# Set DEBUG and VERBOSE preference
If($PSBoundParameters['Debug']){
$DebugPreference = 'Continue'
}
Else{
$DebugPreference = 'SilentlyContinue'
}
If($PSBoundParameters['Verbose']){
$VerbosePreference = 'Continue'
}
Else{
$VerbosePreference = 'SilentlyContinue'
}
# Create Output Object
$Table = @{
"ObjectType"="Message";`
"ObjectValue"=$Message
}
# Stream 1 (Success) - output object
New-Object psobject -Property $Table | select "ObjectType","ObjectValue"
# Stream 4 (Verbose)
Write-Verbose "(DON'T WANT THIS MESSAGE ON CONSOLE, ONLY IN LOG FILE) - Outputting Verbose message: $Message"
# Stream 5 (Debug)
Write-Debug "(DON'T WANT THIS MESSAGE ON CONSOLE, ONLY IN LOG FILE) - Outputting Debug message: $Message"
} # End of function Print-Message
cls
# LogFiles
$LogFileTranscript = "C:\temp\LogFile-TranscriptMethod.log"
If(test-path $LogFileTranscript){ Clear-Content $LogFileTranscript }
$LogFileRedirection = "C:\temp\LogFile-RedirectionMethod.log"
If(test-path $LogFileRedirection){ Clear-Content $LogFileRedirection }
# Results File
$ResultsFile = "C:\temp\ResultsFile.csv"
If(test-path $ResultsFile){ Clear-Content $ResultsFile }
#########################
# Transcript Method #
#########################
Write-Host "Starting Transcript method" -ForegroundColor Yellow
# This "Transcript" method still outputs the Verbose and Debug logs to the console, which I would like to suppress
Start-Transcript -Path $LogFileTranscript
# Run function
Output-Message -Message "Transcript Method" -Verbose -Debug | Export-Csv $ResultsFile -NoTypeInformation -Append
Stop-Transcript
##########################
# Redirection Method #
##########################
Write-Host "Starting Redirection method" -ForegroundColor Yellow
# This "Redirection" method suppresses output to the console, which is good, but by nature it also outputs
# the "results" of the Output-Message function to the log file, since the results are part of Stream 1.
# Thus, there is no data in Stream 1 left for the Export-CSV function, and so nothing from this "redirection"
# method gets output to the Results file.
1..100 | foreach{
Output-Message -Message "$_ - Redirection Method" -Verbose -Debug 5>&1 4>&1 >> $LogFileRedirection | Export-Csv $ResultsFile -NoTypeInformation -Append
Output-Message -Message "$_ - Redirection Method All At Once" -Verbose -Debug *>> $LogFileRedirection | Export-Csv $ResultsFile -NoTypeInformation -Append
}
# Open our files for review
notepad $LogFileTranscript
notepad $LogFileRedirection
Invoke-Item $ResultsFile