Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

powershell indentation

Tags:

powershell

I'm writing a large script that deploys an application. This script is based on several nested function calls.

Is there any way to "ident" the output based on the depth?

For example, I have:

function myFn()
{
    Write-Host "Start of myfn"
    myFnNested()
    Write-Host "End of myfn"
}
function myFnNested()
{
    Write-Host "Start of myFnNested"
    Write-Host "End of myFnNested"
}

Write-Host "Start of myscript"
Write-Host "End of myscript"

The output of the script will be :

Start of myscript
Start of myfn
Start of myfnNested
End of myFnNested
End of myFn
End of myscript

What I want to achieve is this output :

Start of myscript
  Start of myfn
    Start of myfnNested
    End of myFnNested
  End of myFn
End of myscript

As I don't want to hardly code the number of spaces (since I does not know the depth level in complex script). How can I simply reach my goal ?

Maybe something like this?

function myFn()
{
    Indent()
    Write-Host "Start of myfn"
    myFnNested()
    Write-Host "End of myfn"
    UnIndent()
}
function myFnNested()
{
    Indent()
    Write-Host "Start of myFnNested"
    Write-Host "End of myFnNested"
    UnIndent()
}

Write-Host "Start of myscript"
Write-Host "End of myscript"
like image 736
Steve B Avatar asked Jun 30 '11 08:06

Steve B


People also ask

Do spaces matter in PowerShell?

In reality, it does not matter. If a script is not working, it is not because of a space between these things. The following image shows that both commands will work, but with proper spacing, the commands are easier to read. Spaces in expressions also make things easier to read, but they do not affect the code.

What does the command @() mean in PowerShell?

In PowerShell V2, @ is also the Splat operator. PS> # First use it to create a hashtable of parameters: PS> $params = @{path = "c:\temp"; Recurse= $true} PS> # Then use it to SPLAT the parameters - which is to say to expand a hash table PS> # into a set of command line parameters.

What are types of formatting in PowerShell?

They let you select which properties you want to show. This article describes the Format-Wide , Format-List , and Format-Table cmdlets. Each object type in PowerShell has default properties that are used when you don't specify which properties to display.

How do I format a PowerShell script?

Formatting a PowerShell Script Note: Workspace formatting settings are only used if you've opened the folder rather than an individual file. Press SHIFT+ALT+F (or press F1 and type Format and select Format Document). The code is now all well formatted, so save the document.


2 Answers

You could use a wrapper function around write-host which used $MyInvocation to determine the stack depth to create a number of spaces to prefix the message.

Combine this with the -scope ‹n› parameter of Get-Variable to pull out each calling level… something like the showstack function adapted from Windows PowerShell In Action (Payette, 1st Ed):

function ShowStack {
  trap { continue; }
  0..100 | Foreach-Object {
    (Get-Variable -scope $_ 'MyInvocation').Value.PositionMessage -replace "`n"
  }
}

You'll need the maximum value of $_ in the pipeline before Get-Variable fails for scope count being too high.

like image 133
Richard Avatar answered Oct 09 '22 15:10

Richard


Check out this script http://poshcode.org/scripts/3386.html

If you load up that Write-Verbose wrapper, you can set $WriteHostAutoIndent = $true and then just call Write-Host and it will be indented based on stack depth. So given these functions as you defined them originally:

function myFn()
{
   Write-Host "Start of myfn"
   myFnNested
   Write-Host "End of myfn"
}
function myFnNested()
{
   Write-Host "Start of myFnNested"
   Write-Host "End of myFnNested"
}

With no changes, you can just dot-source a script file with that Write-Host wrapper function in it:

C:\PS> . C:\Users\Jaykul\Documents\WindowsPowerShell\PoshCode\3386.ps1

And then merely set the preference variable before you call your function:

C:\PS> $WriteHostAutoIndent = $true
C:\PS> myFn
  Start of myfn
    Start of myFnNested
    End of myFnNested
  End of myfn

Beautiful indented output, like magic ;-)

like image 29
Jaykul Avatar answered Oct 09 '22 16:10

Jaykul