0
0
Scenario
I would like to see the output of powershell commands that are executed inside a method of an object, in the same way I see them "live/when they are happening" when they are not inside the object.
Examples
To illustrate the undesired difference, I will show 2 scripts, the first one shows the output of the commnad, the 2nd does not. Both are run by opening powershell, browsing to their directory and ran with ./<scriptname>.ps1
- Consider
scriptA.ps1
with content:
lxrun /install /y
Which produces the desired outcome of:
Warning: lxrun.exe is only used to configure the legacy Windows Subsystem for Linux distribution. Distributions can be installed by visiting the Windows Store: https://aka.ms/wslstore This will install Ubuntu on Windows, distributed by Canonical and licensed under its terms available here: https://aka.ms/uowterms The legacy Windows Subsystem for Linux distribution is already installed.
scriptB.ps1
with content:
# runs single command
Class Object{
runCommand(){
lxrun /install /y
}
}
# create object
[Object] $object = [Object]::new()
# execute command in method runCommand() of [Object] object
$object.runCommand()
Which does not show any output at all.
Attempts
All attempts are made inside the following script, at line: <command here>
# runs single command
Class Object{
runCommand(){
`<command here>`
}
}
- Line:
Write-Output (lxrun /install /y)
Resulting output:(no output)
- Line:
Write-Host (lxrun /install /y)
Resulting output:Correct content, but lost/changed legible text formatting:
W a r n i n g : l x r u n . e x e i s o n l y u s e d t o c o n f i g u r e t h e l e g a c y W i n d o w s S u b s y s t e m f o r L i n u x d i s t r i b u t i o n . D i s t r i b u t i o n s c a n b e i n s t a l l e d b y v i s i t i n g t h e W i n d o w s S t o r e : h t t p s : / / a k a . m s / w s l s t o r e T h i s w i l l i n s t a l l U b u n t u o n W i n d o w s , d i s t r i b u t e d b y C a n o n i c a l a n d l i c e n s e d u n d e r i t s t e r m s a v a i l a b l e h e r e : h t t p s : / / a k a . m s / u o w t e r m s T h e l e g a c y W i n d o w s S u b s y s t e m f o r L i n u x d i s t r i b u t i o n i s a l r e a d y i n s t a l l e d .
- Line:
Write-Host (lxrun /install /y) | Out-Host
Resulting output: same as in attempt 2.
- Line:
Write-Host (lxrun /install /y) | Out-Default
Resulting output: same as in attempt 2.
- Line:
Write-Host (lxrun /install /y) | Out-String
Resulting output: same as in attempt 2
- Line:
write-verbose (lxrun /install /y)
Resulting output:(no output)
Write-Verbose : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Message'. Specified method is not supported. At F:\path to example script\example.ps1:30 char:23 + write-verbose (lxrun /install /y) + ~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Write-Verbose], ParameterBindingException + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.WriteVerboseCommand
- Line:
write-verbose (lxrun /install /y) -Verbose
Resulting output:same as in 6 (except when the line at which the error occurs, the -Verbose is included)
- Line:
(lxrun /install /y) | Write-Host
Resulting output: Better readible but still not the nor
o c o n f i g u r e t h e l e g a c y W i n d o w s S u b s y s t e m f o r L i n u x d i s t r i b u t i o n . D i s t r i b u t i o n s c a n b e i n s t a l l e d b y v i s i t i n g t h e W i n d o w s S t o r e : h t t p s : / / a k a . m s / w s l s t o r e T h i s w i l l i n s t a l l U b u n t u o n W i n d o w s , d i s t r i b u t e d b y C a n o n i c a l a n d l i c e n s e d u n d e r i t s t e r m s a v a i l a b l e h e r e : h t t p s : / / a k a . m s / u o w t e r m s T h e l e g a c y W i n d o w s S u b s y s t e m f o r L i n u x d i s t r i b u t i o n i s a l r e a d y i n s t a l l e d . ```
- Line:
Write-Verbose -Message (lxrun /install /y)
Resulting output:
Write-Verbose : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Message'. Specified method is not supported.
At G:/path to file\example.ps1:35 char:32
+ Write-Verbose -Message (lxrun /install /y)
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Write-Verbose], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.WriteVerboseCommand
- Line:
Write-Verbose -Message lxrun /install /y
Resulting output: same as in attempt 9
- Line:
Write-Verbose -Message (lxrun /install /y) -Verbose
Resulting output: same as in attempt 9 (except when the line at which the error occurs, the -Verbose is included)
- Based on the question and answers linked in the comments, I modified the script to:
# runs single command
#[CmdletBinding(SupportsShouldProcess=$true)]
[CmdletBinding()]
Param()
Class Object{
runCommand(){
lxrun /install /y|Write-Verbose
}
}
# create object
[Object] $object = [Object]::new()
# execute command in method runCommand() of [Object] object
$object.runCommand()
which is called with the -Verbose parameter when running it: ./example.ps1 -Verbose
. It returns a black and yellow text:
VERBOSE: W a r n i n g : l x r u n . e x e i s o n l y u s e d t o >c o n f i g u r e t h e l e g a c y W i n d o w s S u b s y s t e m f o r L i n u x d i s t >r i b u t i o n . VERBOSE: VERBOSE: VERBOSE: D i s t r i b u t i o n s c a n b e i n s t a l l e d b y v >i s i t i n g t h e W i n d o w s S t o r e : VERBOSE: VERBOSE: VERBOSE: h t t p s : / / a k a . m s / w s l s t o r e VERBOSE: VERBOSE: VERBOSE: VERBOSE: VERBOSE: VERBOSE: T h i s w i l l i n s t a l l U b u n t u o n W i n d o w s >, d i s t r i b u t e d b y C a n o n i c a l a n d l i c e n s e d u n d e r i t s t e r >m s a v a i l a b l e h e r e : VERBOSE: VERBOSE: VERBOSE: h t t p s : / / a k a . m s / u o w t e r m s VERBOSE: VERBOSE: VERBOSE: VERBOSE: VERBOSE: VERBOSE: T h e l e g a c y W i n d o w s S u b s y s t e m f o r L i >n u x d i s t r i b u t i o n i s a l r e a d y i n s t a l l e d . VERBOSE: VERBOSE: VERBOSE:
Where from what I understood the Param()
is included to pass/absorb the -Verbose
argument, and the [CmdletBinding()]
enables let binding the way a cmdlet
does it, instead of the "normal" way a script does. I still need to understand what that difference is/means. And the the formatting is not yet correct/desired with this Write-Verbose implementation.
Question
How do I write the output of a command on the powershell terminal without delay, without losing it's original formatting (as with scriptA.ps1
)?
Note
One could build a parser, but I think there might be more efficient and faster solutions which I have not yet found.
1
So which instance generated the output? The one with
– Seth – 2019-08-22T09:44:31.427Write-Host
or the one withWrite-Output
? One Option would be to useWrite-Verbose
.1@Seth I apologize for the unclarity, I have restructured the attempts which show that the
Write-Host
option generated outputs at attempts 3,4,5,8 (In a "wrong"/different formatting), while theWrite-Output
at attempt 1, did not generate an output.Thank you for your suggestion, I incorporated the results of the attempts in the initial question, and will proceed debugging their respective error messages. – a.t. – 2019-08-22T15:56:13.5131
Write-Verbose
didn't produce any output because you didn't change$VerbosePreference
and actually made sure that you're supporting-Verbose
for your class. about_Classes also points out that using Write-Host essentially violates PowerShell principals and why you're not seeing any output by default. – Seth – 2019-08-23T05:26:07.570