How can I hide the progress display of Invoke-WebRequest
? I do a lot of successive requests and have my own Write-Progress
display that I use, so I don't need the built-in one popping up underneath it every time.
I use the mshtml results (the IE COM object) that are created from the result of Invoke-WebRequest
automatically, so I can't switch to a WebClient
or something like that, unless someone provides instructions on how to get an mshtml object from a WebClient request.
Use the $progressPreference variable. It should have a value of 'Continue' by default unless you've edited it elsewhere, which tells Powershell to display the progress bar. Since you mentioned that you have your own custom progress displays, I would reset it immediately after the cmdlet is executed. For example:
$ProgressPreference = 'SilentlyContinue' # Subsequent calls do not display UI.
Invoke-WebRequest ...
$ProgressPreference = 'Continue' # Subsequent calls do display UI.
Write-Progress ...
More info on preference variables at about_preference_variables. Here's the entry for $ProgressPreference:
$ProgressPreference
-------------------
Determines how Windows PowerShell responds to progress updates
generated by a script, cmdlet or provider, such as the progress bars
generated by the Write-Progress cmdlet. The Write-Progress cmdlet
creates progress bars that depict the status of a command.
Valid values:
Stop: Does not display the progress bar. Instead,
it displays an error message and stops executing.
Inquire: Does not display the progress bar. Prompts
for permission to continue. If you reply
with Y or A, it displays the progress bar.
Continue: Displays the progress bar and continues with
(Default) execution.
SilentlyContinue: Executes the command, but does not display
the progress bar.
Here is a reusable function to temporarily hide the progress of any script block and automatically restore the progress preference when the script block ends, even if an exception (script-terminating error) is thrown by the script block.
# Create an in-memory module so $ScriptBlock doesn't run in new scope
$null = New-Module {
function Invoke-WithoutProgress {
[CmdletBinding()]
param (
[Parameter(Mandatory)] [scriptblock] $ScriptBlock
)
# Save current progress preference and hide the progress
$prevProgressPreference = $global:ProgressPreference
$global:ProgressPreference = 'SilentlyContinue'
try {
# Run the script block in the scope of the caller of this module function
. $ScriptBlock
}
finally {
# Restore the original behavior
$global:ProgressPreference = $prevProgressPreference
}
}
}
Usage example:
Invoke-WithoutProgress {
# Here $ProgressPreference is set to 'SilentlyContinue'
Invoke-WebRequest ...
}
# Now $ProgressPreference is restored
Write-Progress ...
Notes:
New-Module
call is there so the script block passed to Invoke-WithoutProgress
doesn't run in a new scope (allowing it to directly modify surrounding variables, similar to ForEach-Object
's script block). See this answer for more information.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With