Payette's Windows Powershell in Action: the only true powershell documentation

Welcome Forums General PowerShell Q&A Payette's Windows Powershell in Action: the only true powershell documentation

This topic contains 9 replies, has 4 voices, and was last updated by

js
 
Participant
2 months, 4 weeks ago.

  • Author
    Posts
  • #160829
    js

    Participant
    Topics: 25
    Replies: 677
    Points: 1,623
    Helping Hand
    Rank: Community Hero

    This isn't really a question. But it seems to me there's a disconnect between Bruce Payette's book and the official documentation. I had no idea I could do all this stuff. I guess some are in the docs, but are not done commonly. Although I would never use '>' and '>>', since they encode in unicode.

    # where method (and foreach method) which are faster
    (Get-Process | sort Handles).where({$_.Handles -gt 1000}, 'Until')
    (Get-Process notepad).foreach('Kill')
    
    # hide output with [void]
    [void] $(Write-Output "discard me")
    
    # invoke a method with a variable
    $method = 'sin'
    [math]::$method.Invoke(3.14)
    
    # swap two variables:
    $a,$b = $b,$a
    
    # reference any psdrive like C: with a variable, but need the curly braces {} 
    # (but how do I pass in "$path = 'file.txt'?)
    # and search and replace a file
    ${c:file.txt} = ${c:file.txt} -replace 'oldstring','newstring'
    
    # and swap two files
    ${c:file1.txt},${c:file2.txt} = ${c:file2.txt},${c:file1.txt}
    
    # $foreach and movenext, ok this is in the doc but I didn't know it
    foreach ($i in 1..10)
    { [void] $foreach.MoveNext(); $i + $foreach.Current }
    
    # foreach-object operation statement, in docs but didn't know
    ps | foreach-object name
    'hi.there' | Foreach-object Split .
    
    # using assemply (didn't know using namespace)
    using assembly System.Windows.Forms
    using namespace System.Windows.Forms
    [messagebox]::show('hello world')
    
    # an assignment is an expression
    if (2 -eq ($a = 2)) { 'yes' }
    
    # and then with redirection save output and error to separate variables
    $err = $( $output = ls foo3 ) 2>&1
    
    # restrict var to int, in doc but didn't know
    [int]$a = 1
    
    # restrict length of var like in advanced functions
    [ValidateLength(0,5)] [string] $cv = ''
    
    # subexpressions $() aren't just for double quoted strings, 
    # you can put in multiple statements with semicolons and keywords like if and foreach
    # and put them anywhere you can put an expression or pipeline
    $( echo hi; echo there ) | measure
    if ( $(if (1 -eq 1) {'yes'}) -eq 'yes' ) { 'yep' }
    for ($i=0; $($y = $i*2; $i -lt 5); $i++) { $y }
    
    # labels, in doc but didn't know
    # loop label, break out of both loops
    $target = 'outer'
    :outer while (1) {
      while(1) {
        break $target
      }
    }
    
    # switch, so many things, arrays and $_, in doc but didn't know
    switch(1,2,3,4,5,6) {
      {$_ % 2} {"Odd $_"; continue}
      4 {'FOUR'}
      default {"Even $_"}
    }
    
    # $switch and movenext and current
    switch ($options){
      '-a' { $a=$true }
      '-b' { [void] $switch.MoveNext(); $b= $switch.Current }
      '-c' { $c=$true }
      '-d' { $d=$true }
    }
    
    # three script blocks with foreach-object -process arg (for begin, process, end)
    gps svchost | foreach-object {$t=0} {$t+=$_.handles} {$t}
    
    # -replace has a lot of codes for the 2nd arg, 
    # doc is in some regex doc that's not linked from the about comparison operators page
    $number Substitutes the last submatch matched by group number.
    ${name} Substitutes the last submatch matched by a named capture of the form (?).
    $$ Substitutes a single "$" literal.
    $& Substitutes a copy of the entire match itself.
    $` Substitutes all the text from the argument string before the matching portion.
    $' Substitutes all the text of the argument string after the matching portion.
    $+ Substitutes the last submatch captured.
    $_ Substitutes the entire argument string.
    
    # pipes in simple funcs ($input has a .movenext() too)
    function sum {
      $total=0;
      foreach ($n in $input) { $total += $n }
      $total
    }
    1,2,3 | sum
    
  • #160842

    Senior Moderator
    Topics: 8
    Replies: 1041
    Points: 3,438
    Helping Hand
    Rank: Community Hero

    yes, that book is the real bible...

    better to make above all as a blog post or in github as markdown with a nice title, let the unknown know it.

    • #160848
      js

      Participant
      Topics: 25
      Replies: 677
      Points: 1,623
      Helping Hand
      Rank: Community Hero

      Where in github?

  • #160857

    Senior Moderator
    Topics: 8
    Replies: 1041
    Points: 3,438
    Helping Hand
    Rank: Community Hero

    In your's, if you have github account. Let other's correct/contribute.

  • #160979

    Participant
    Topics: 12
    Replies: 232
    Points: 466
    Helping Hand
    Rank: Contributor

    Haven't read the book but I don't think it's that common that people know that you can create "anonymous" functions.

    E.g.

    # if the leftover is 1 it's and odd number, else it's even.
    $oddOrEven = {param($a) if($a % 2){"Odd"}else{"Even"}}
    
    # call the anonymous function
    &$oddOrEven 5
    
    • #160994
      js

      Participant
      Topics: 25
      Replies: 677
      Points: 1,623
      Helping Hand
      Rank: Community Hero

      Thanks. I haven't gotten to the metaprogramming chapter yet.

  • #161378
    js

    Participant
    Topics: 25
    Replies: 677
    Points: 1,623
    Helping Hand
    Rank: Community Hero

    Oh, get-content and set-content work with all providers. Here it is with variables.

    PS /Users/js> get-content variable:a | set-content -value 'there'
    PS /Users/js> $a
    there
    

    Too bad you can't use scriptblock paramters with -value since it's an object. (The path is being piped in as PSPath.)

    PS /Users/js> get-content variable:a | set-content -value {$_ -replace 'there','hi'} 
    PS /Users/js> $a
     $_ -replace 'there','hi' 
    
  • #161391

    Senior Moderator
    Topics: 8
    Replies: 1041
    Points: 3,438
    Helping Hand
    Rank: Community Hero

    do you know the stream technique

    Mathias showed me this first...

    Set-Content -Path c:\temp\test.txt -Value YouCanSeeMe
    Set-Content -Path c:\temp\test.txt -Value YouCannotSeeMe -Stream foo
    Notepad c:\temp\test.txt
    Get-Content -Path c:\temp\test.txt
    Get-Content -Path c:\temp\test.txt -Stream foo
    
  • #161403

    Participant
    Topics: 2
    Replies: 999
    Points: 1,946
    Helping Hand
    Rank: Community Hero

    I have and used every version of this book since he released it.

    It's the default advanced PowerShell book on the market and the one I specifically recommend.

    These should be on every PowerSheller's desk or in electronic form on their devices.

    Beginning —

    Learn Windows PowerShell in a Month of Lunches 3rd Edition
    Donald W. Jones   (Author),‎    Jeffrey Hicks (Author)
    ISBN-13:  978-1617294167
    ISBN-10:  1617294160

    Internediate —

    Windows PowerShell Cookbook: The Complete Guide to Scripting Microsoft's Command Shell 3rd Edition
    Lee Holmes   (Author)
    ISBN-13:  978-1449320683
    ISBN-10:  1449320686

    Advanced —

    Windows PowerShell in Action 3rd Edition
    by Bruce Payette (Author),‎    Richard Siddaway (Author)
    ISBN-13:  978-1633430297
    ISBN-10:  1633430294

  • #162473
    js

    Participant
    Topics: 25
    Replies: 677
    Points: 1,623
    Helping Hand
    Rank: Community Hero

    Get and set a variable in a module scope with the call operator (undocumented):

    # get module object
    $m = get-module counter
    
    & $m Get-Variable count
    & $m Set-Variable count 33
    
    # see func def
    & $m Get-Item function:Get-Count
    
    # run with commandinfo object and call operator
    $d = get-command get-date
    & $d
    
    # set function to scriptblock
    ${function:Set-CountIncrement} = $setIncrement
    
    # scriptblock process block (there are scriptblock begin and end blocks too)
    1..5 | &{process{$_ * 2}}
    

You must be logged in to reply to this topic.