locked
Punctuation problem? How can I make these two lines into a one-liner? RRS feed

  • Question

  • Can anybody tell me why this works:

    $dn = (get-aduser (whoami).substring((whoami).indexof('\') + 1) -properties manager).manager
    get-aduser -Filter { manager -eq $dn }

    but this doesn't work and how I can make it into a one-liner:

    get-aduser -Filter { manager -eq (get-aduser (whoami).substring((whoami).indexof('\') + 1) -properties manager).manager }

    'Punctuation' may not be the right word; it may not be the problem.  But I feel that if I can write two lines and one is just setting a variable the other is just using it, then I ought to be able to combine them into a one-liner.  But I'm not sure where to start on this.  I've tried extra parentheses, e.g.

    get-aduser -Filter { manager -eq ((get-aduser (whoami).substring((whoami).indexof('\') + 1) -properties manager).manager) }

    Quotes didn't work, either.  Am I missing something?

    In case it's not clear, I'm trying to query the directory for all of the people who report to my manager.

    • Edited by SSG31415926 Monday, September 3, 2012 4:45 PM
    Monday, September 3, 2012 4:44 PM

Answers

  • get-aduser -Filter "manager -eq '$((get-aduser (whoami).substring((whoami).indexof("\") + 1) -properties manager).manager)'"

    • Edited by Kazun Monday, September 3, 2012 6:59 PM
    • Proposed as answer by Yan Li_ Tuesday, September 4, 2012 2:26 AM
    • Marked as answer by SSG31415926 Tuesday, September 4, 2012 3:48 PM
    Monday, September 3, 2012 6:58 PM
  • Bruce Payette (programming language designer for PowerShell) calls $() the subexpression operator
    and describes it this way:
     
    Subexpressions group collections
    of statements as opposed
    to being limited to a single
    expression. If the contained
    statements return a single value,
    that value will be returned as a
    scalar. If the statements return
    more than one value, they will be
    accumulated in an array.
     
    $($p = "a*"; get-process $p )
     
    Returns the process
    objects for all
    processes starting
    with the letter a.
     
     
    • Marked as answer by SSG31415926 Tuesday, September 4, 2012 3:49 PM
    Tuesday, September 4, 2012 1:50 PM
  • It's just explaining what the return types will be.

    $() will always return $nul

    $(<expression>) will return $nul if the expression evaluation does not return any objects.

    $(<expression>) will return a scalar (single object) if the expression evaluation returns one object.

    $(<expression>) will return an array of objects if the expression evaluation returns multiple objects.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    • Marked as answer by SSG31415926 Tuesday, September 4, 2012 3:50 PM
    Tuesday, September 4, 2012 2:49 PM

All replies

  • Am I to understand that the semi;colon is not considered a true one liner ?   

    $dn = (get-aduser (whoami).substring((whoami).indexof('\') + 1) -properties manager).manager;get-aduser -Filter { manager -eq $dn }


    Don't forget to mark your posts as answered so they drop off the unanswered post filter. If I've helped you and you want to show your gratitude, just click that green thingy.

    Monday, September 3, 2012 5:34 PM
  • A semi-colon is a substitute for a line break and performs the same function.  This is not a one-liner:

    Write-Host "Hello"; Write-Host "World"

    It is two "lines".


    Grant Ward, a.k.a. Bigteddy

    Monday, September 3, 2012 5:54 PM
  • Gotcha, not good enough for this conversation, but it still fools a six sigma black belt back at the office.

    Don't forget to mark your posts as answered so they drop off the unanswered post filter. If I've helped you and you want to show your gratitude, just click that green thingy.

    Monday, September 3, 2012 6:10 PM
  • get-aduser -Filter "manager -eq '$((get-aduser (whoami).substring((whoami).indexof("\") + 1) -properties manager).manager)'"

    • Edited by Kazun Monday, September 3, 2012 6:59 PM
    • Proposed as answer by Yan Li_ Tuesday, September 4, 2012 2:26 AM
    • Marked as answer by SSG31415926 Tuesday, September 4, 2012 3:48 PM
    Monday, September 3, 2012 6:58 PM
  • Not always.
      - Larry
     
    On 9/3/2012 12:54 PM, Bigteddy wrote:
    > A semi-colon is a substitute for a line break and performs the same function.
     
    Monday, September 3, 2012 9:53 PM
  • Superb!  Thanks.

    Would you mind explaining how the '$( blah )' bit works?

    Tuesday, September 4, 2012 10:09 AM
  • $( ) is the "evaluate" construction.  I should have thought of it.  I'm sure Larry has a better way of putting it, but I think of it as "Evaluate this".

    Grant Ward, a.k.a. Bigteddy

    Tuesday, September 4, 2012 1:13 PM
  • Bruce Payette (programming language designer for PowerShell) calls $() the subexpression operator
    and describes it this way:
     
    Subexpressions group collections
    of statements as opposed
    to being limited to a single
    expression. If the contained
    statements return a single value,
    that value will be returned as a
    scalar. If the statements return
    more than one value, they will be
    accumulated in an array.
     
    $($p = "a*"; get-process $p )
     
    Returns the process
    objects for all
    processes starting
    with the letter a.
     
     
    • Marked as answer by SSG31415926 Tuesday, September 4, 2012 3:49 PM
    Tuesday, September 4, 2012 1:50 PM
  • I believe $ is evaluate ($a evaluates the variable named 'a'). $() is subexpression.

    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Tuesday, September 4, 2012 1:56 PM
  • Yes, I thought I had the name wrong.  That's why I appealed to Larry to help me out with the correct nomenclature.  I didn't learn PS from a book, you see.  (Not that there's anything wrong with learning from a book, it just didn't happen that way for me).


    Grant Ward, a.k.a. Bigteddy

    Tuesday, September 4, 2012 2:00 PM
  • I believe I got that from the language reference.

    Disclaimer:  I printed it out and put it into a binder.  Does that count as a book?


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Tuesday, September 4, 2012 2:04 PM
  • I believe I got that from the language reference.

    Disclaimer:  I printed it out and put it into a binder.  Does that count as a book?


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "


    It most certainly does.  I've just Googled, and can't find this language reference you speak of.  Have you got a link?

    Grant Ward, a.k.a. Bigteddy

    Tuesday, September 4, 2012 2:13 PM
  • The proper name is "Windows Powershell Language Specification".

    You can download it here:

    http://www.microsoft.com/en-us/download/details.aspx?id=9706


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Tuesday, September 4, 2012 2:20 PM
  • Thanks.

    Grant Ward, a.k.a. Bigteddy

    Tuesday, September 4, 2012 2:29 PM
  • Thanks for that link to the downloadable "docx" version of it.
    I hope we discover a PowerShell 3.0 version of it, as well.
     From the "Windows PowerShell Language Specification Version 2.0"
     
    7.1.6 $(…) operator
    Syntax:
    sub-expression:
    $(   new-lines opt   statement-list opt   new-lines opt   )
    Description:
    If statement-list is omitted, the result is $null. Otherwise, statement-list is evaluated.  Any
    objects written to the pipeline as part of the evaluation are collected in an unconstrained
    1-dimensional array, in order.  If the array of collected objects is empty, the result is $null.
    If the array of collected objects contains a single element, the result is that element; otherwise,
    the result is the unconstrained 1-dimensional array of collected results.
     
    Tuesday, September 4, 2012 2:35 PM
  • Well, that's as clear as mud.  I honestly think my explanation, silly as it was, is more understandable.

    Grant Ward, a.k.a. Bigteddy

    Tuesday, September 4, 2012 2:43 PM
  • It's just explaining what the return types will be.

    $() will always return $nul

    $(<expression>) will return $nul if the expression evaluation does not return any objects.

    $(<expression>) will return a scalar (single object) if the expression evaluation returns one object.

    $(<expression>) will return an array of objects if the expression evaluation returns multiple objects.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    • Marked as answer by SSG31415926 Tuesday, September 4, 2012 3:50 PM
    Tuesday, September 4, 2012 2:49 PM
  • Sometimes the "formal" spec is handy, in spite of it being overly wordy.
    At least it establishes some terminology.  In this case "sub-expression" to describe the $() operator.
     
    What is interesting to me about $() is that it can contain more than one statement.
     
    Tuesday, September 4, 2012 2:59 PM
  • So basically the $(Blah) part allows you to use a more complex variable than can usually be done inline.  Could be useful in certain instances. 

    Don't forget to mark your posts as answered so they drop off the unanswered post filter. If I've helped you and you want to show your gratitude, just click that green thingy.


    Tuesday, September 4, 2012 3:01 PM
  • And those <expression>s can contain multiple statements.
     
     
    Tuesday, September 4, 2012 3:02 PM
  • So basically the $(Blah) part allows you to use a more complex variable than can usually be done inline.  Could be useful in certain instances. 

    Don't forget to mark your posts as answered so they drop off the unanswered post filter. If I've helped you and you want to show your gratitude, just click that green thingy.



    Yes.

    Grant Ward, a.k.a. Bigteddy

    Tuesday, September 4, 2012 3:03 PM
  • On 9/3/2012 12:54 PM, Bigteddy wrote:
     > A semi-colon is a substitute for a line break and performs the same function. This is not a
    one-liner:
     >
     > Write-Host "Hello"; Write-Host "World"
     >
     > It is two "lines".
     >
    .
    .
    Consider these two lines executed separately:
     
    C:> get-process powershell
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
    -------  ------    -----      ----- -----   ------     -- -----------
        400      25    59132      59180   580     1.06   5140 powershell
     
    C:> get-service Schedule
    Status   Name               DisplayName
    ------   ----               -----------
    Running  Schedule           Task Scheduler
    .
    .............................................................
    .
    Now run them as a single line:
     
    C:> get-process powershell; get-service Schedule
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
    -------  ------    -----      ----- -----   ------     -- -----------
        476      25    59132      59180   580     1.12   5140 powershell
    Status      : Running
    Name        : Schedule
    DisplayName : Task Scheduler
    .
    Note the difference in the output formatting.
    .
    - Larry
     
    Tuesday, September 4, 2012 3:16 PM
  • But if I execute the two commands, each on it's own line in the ISE, I get this formatting:

    PS C:\scripts> get-process powershell
    get-service Schedule
    
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName                                                                                                    
    -------  ------    -----      ----- -----   ------     -- -----------                                                                                                    
        199      14    14380       8892   483     0.20   5544 powershell                                                                                                     
    
    Status      : Running
    Name        : Schedule
    DisplayName : Task Scheduler

    ...which is the same as your semi-colon formatting.  So which one is right?

    Grant Ward, a.k.a. Bigteddy

    Tuesday, September 4, 2012 3:22 PM
  • What's more, if I save those two commands as a script, and run it in a normal Powershell console, the formatting is the same as above.

    Grant Ward, a.k.a. Bigteddy

    Tuesday, September 4, 2012 3:29 PM
  • This

    get-process powershell;get-service Schdeule 

    Is equivalent to this:

    @($(get-process powershell), $(get-service Schedule)) | format-table

    Powershell is trying to display the collection using the default formatting (format-table), but they are dissimilar objects, so it reverts to format-list for the second because the properties don't line up with the table headings, which were taken from the first object.

    This:

    get-process Powershell 
    get-service Schedule 


    is equivalent to:

    get-process Powershell | ft
    get-service Schedule | ft

    And each one gets it's own table headings.

    Edit:

    When you're working from a command prompt, hitting Enter on a completed line effectively send the output through the default fomatter, and then to the default destination.  (ie it adds | format-table | out-default).


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "


    • Edited by mjolinor Tuesday, September 4, 2012 3:52 PM
    Tuesday, September 4, 2012 3:41 PM
  • They are both "right".  The output formatter was not designed to allow objects of different types
    to be formatted with different formatters.
     
    I sure wish they would change that.  It is confusing.
      - Larry
     
    Tuesday, September 4, 2012 3:41 PM