Open benrobot opened 3 years ago
@benrobot
If you want to output debug log without user interactive, please don't user -Debug. Please set $DebugPreference = "Continue"
, and then run the cmdlet.
You can see more details in https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.1#debugpreference
@blueww Thank you. Using $DebugPreference = "Continue"
instead of -Debug
worked as you said it would. For my needs it appears that using $DebugPreference = "Continue"
will be sufficient (actually, better than adding -Debug
everywhere).
With regards to adding -Debug
, is the change in behavior intentional?
@benrobot
Good to know $DebugPreference = "Continue"
is sufficient for your scenario.
But I don't quite understand your question "is the change in behavior intentional?" which change and which behavior do you mean?
With -Debug, the cmdlet will always have user interactive.
If you just want debug log without user interactive, you can use $DebugPreference = "Continue"
Please review https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.1#debugpreference, see if it can answer your question.
@benrobot , below page describes the behavior change with debug parameter. https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.1#-debug
@benrobot , below page describes the behavior change with debug parameter. https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.1#-debug
I read the description. The only part that might explain the behavior is
In interactive mode, the Debug parameter overrides the value of the $DebugPreference variable for the current command, setting the value of $DebugPreference to Inquire.
However, there are few problems with this:
pwsh -NonInteractive .\Deploy.ps1 -resourceGroupName "Redacted_resource_group" -storageAccountName "redactedstoragename" -blobContainerName "redacted-blob-name" -someFilePath "./somefile.txt" *> almost_all_output.log
.It appears the command Set-AzStorageBlobContent -Debug -Confirm:$False -Force ...
attempts to confirm the action (after file upload was completed) with the user even when it is in NonInteractive mode; this results in the error PowerShell is in NonInteractive mode. Read and Prompt functionality is not available.
In addition, adding -Verbose seems to fix the issue: | Command | Result |
---|---|---|
pwsh -NonInteractive Set-AzStorageBlobContent -Confirm:$False -Force ... |
Works as expected; no prompt and no error. | |
pwsh -NonInteractive Set-AzStorageBlobContent -Confirm:$False -Force -Debug ... |
Throws PowerShell is in NonInteractive mode. Read and Prompt functionality is not available. | |
pwsh -NonInteractive Set-AzStorageBlobContent -Confirm:$False -Force -Debug -Verbose ... |
Works as expected; no prompt and no error. |
@benrobot
For run cmdlet in NonInteractive mode, please use $DebugPreference = "Continue", instead of adding -Debug. Do you have any specific reason that must add -debug.
@dingmeng-xue As the questions is mostly on -debug and $DebugPreference behavior, but not for specific cmdlet behaviors, could you please help to answer this?
@benrobot
For run cmdlet in NonInteractive mode, please use $DebugPreference = "Continue", instead of adding -Debug. Do you have any specific reason that must add -debug.
For my script, using $DebugPreference = "Continue"
works. I just want to report a bug regarding the behavior of -Debug
. The documentation states that using -Debug
in non-interactive mode should set $DebugPreference = "Continue"
. But it appears that Set-AzStorageBlobContent is not honoring this convention.
In non-interactive mode, the Debug parameter overrides the value of the $DebugPreference variable for the current command, setting the value of $DebugPreference to Continue.
I believe this worth fixing or documenting because I regularly use -Debug
while writing scripts and I use it with the assumption that it will behave like the documentation states. For example, I recently lost a few hours trying to understand why Set-AzStorageBlobContent was causing my CI/CD pipeline to complain about a prompt in non-interactive mode. I read and re-read the documentation about -Force
and -Confirm:$False
to make sure I was suppressing the prompts correctly but it didn't help. Then I just started randomly removing parameters to see what would happen. The -Debug
parameter was the last one I removed because, one, I wanted to see the output, and two, the -Debug
switch was the last parameter I expected to have broken my script.
@benrobot Thanks for the clarify!
The failure when run Set-AzStorageBlobContent -Confirm:$False -Force -Debug
in NonInteractive mode, is not from debug log, but from verbose log. So when you add -Verbose
it will not prompt to confirm verbose.
The stake track for this is:
System.Management.Automation.PSInvalidOperationException: PowerShell is in NonInteractive mode. Read and Prompt functionality is not available.
at Microsoft.PowerShell.ConsoleHostUserInterface.HandleThrowOnReadAndPrompt()
at Microsoft.PowerShell.ConsoleHostUserInterface.PromptForChoice(String caption, String message, Collection`1 choices, Int32 defaultChoice)
at System.Management.Automation.Internal.Host.InternalHostUserInterface.PromptForChoice(String caption, String message, Collection`1 choices, Int32 defaultChoice)
at System.Management.Automation.MshCommandRuntime.InquireHelper(String inquireMessage, String inquireCaption, Boolean allowYesToAll, Boolean allowNoToAll, Boolean replaceNoWithHalt, Boolean hasSecurityImpact)
at System.Management.Automation.MshCommandRuntime.WriteVerbose(VerboseRecord record, Boolean overrideInquire)
at System.Management.Automation.Cmdlet.WriteVerbose(String text)
at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.WriteVerbose(String text)
at Microsoft.WindowsAzure.Commands.Storage.Common.StorageCloudCmdletBase`1.WriteTaskSummary()
at Microsoft.WindowsAzure.Commands.Storage.Blob.StorageDataMovementCmdletBase.DoEndProcessing()
at Microsoft.WindowsAzure.Commands.Storage.Blob.SetAzureBlobContentCommand.DoEndProcessing()
at Microsoft.WindowsAzure.Commands.Storage.Blob.SetAzureBlobContentCommand.EndProcessing()
at System.Management.Automation.CommandProcessorBase.Complete()
@dingmeng-xue Do you have any idea on this?
It looks other cmdlet also has similar behavior, like run Add-AzAccount
in NonInteractive mode, will fail with warning message prompt, until add-WarningAction Continue
.
As I see, when -Debug
is added, debug/warning/verbose/shouldprocess/... will all be output and have prompt, but they will need different parameters to suppress prompt in NonInteractive mode.
-Debug
for Debug log-Verbose
for verbose log-WarningAction Continue
for warning message-Confirm:$False
for shouldprocess However, set $DebugPreference = "Continue" looks can suppress all of them.
Cmdlet has attribute [CmdletBinding(SupportsShouldProcess=$true)]
. -Force
, -WhatIf
and -Confirm
are added due to SupportsShouldProcess.
Adding -Confirm
will show additional prompt Are you sure you want to perform this action?
before cmdlet execution. -Confirm:$false
or without -confirm
will skip that prompt. If cmdlet implements internal prompt logic like current one, another prompt will be shown up. -Force
is used to suppress that prompt.
If cmdlet has any prompt, PowerShell in NonInteractive mode shows error Read and Prompt functionality is not available.
You need to suppress prompt with -Force
and without -Confirm
to avoid both prompts which lead above error.
-Debug
triggers above 2 prompts as well. The behavior likes -Confirm
. -Force
can suppress the second prompt but the first prompt is still shown up.
So, $DebugPreference = "Continue"
and -Force
are recommended combination for executing cmdlet with SupportsShouldProcess
attribute in PowerShell non-interactive mode.
-Debug
triggers above 2 prompts as well. The behavior likes-Confirm
.-Force
can suppress the second prompt but the first prompt is still shown up.
@dingmeng-xue Is this behavior documented somewhere? If not, maybe we can add this information to https://docs.microsoft.com/en-us/powershell/azure/troubleshooting?view=azps-6.4.0 or some other more global location.
I ask because the page https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.1#-debug states
In non-interactive mode, the Debug parameter overrides the value of the $DebugPreference variable for the current command, setting the value of $DebugPreference to Continue.
which appears to be different from your statement.
HI @benrobot,
I believe there is no official doc because the behavior depends cmdlet implementation. You can try below example code. It's a typical logic and simplified code of Azure PowerShell cmdlet. You need to name it as foo.psm1 and then import it as module.
function Test-MyCode {
[CmdletBinding(SupportsShouldProcess=$true)]
param(
# This switch allows the user to override the prompt for confirmation
[switch]$Force
)
if ($PSCmdlet.ShouldProcess('Target')) {
if ($Force -or $PSCmdlet.ShouldContinue('Do you want to continue?', 'Caption')) {
Write-Host "Do action"
}
}
Write-Debug "This is debug message"
Write-Verbose "This is verbose message"
Write-Host "Test"
}
But we cannot confirm the implementation of all cmdlets of Azure PowerShell following the same approach. It's not easy to track kinds of this issue. So, we only suggest user to use $DebugPreference = "Continue"
instead of appending -Debug
.
I agree with you that -Debug
seems do more than $DebugPreference = "Continue"
. It's a general question to PowerShell. It should be discussed in its repo https://github.com/PowerShell/PowerShell/issues.
Description
The
-Debug
switch ~(as well as$DebugPreference='Continue'
)~ causes the-Confirm:$False
switch to be ignored in Set-AzStorageBlobContent cmdlet. If this is desired behavior then maybe it should be documented on the troubleshooting page https://docs.microsoft.com/en-us/powershell/azure/troubleshooting?view=azps-6.4.0.I'm using these cmdlets in my CI/CD pipeline (issue is reproduced both on the pipeline as well as on my local machine) and I like to have verbose output so I know exactly what happened should something go wrong. The behavior presented here prevents me from using the
-Debug
switch because the CI/CD pipeline throws an exception likePowerShell is in NonInteractive mode. Read and Prompt functionality is not available.
:Steps to reproduce
Deploy.ps1 Deploy.ps1.txt
Environment data
Module versions
Debug output
Console Output (also creates file
almost_all_output.log
)Contents of
almost_all_output.log
almost_all_output.log.txtError output
There was no error so there's nothing to report in this section