locked
Using the $() subexpression operator RRS feed

  • Question

  • I have come across these examples, which explain the use to me:

    # Embedding a subexpression in text:
    "One CD has the capacity of $(720MB / 1.44MB) diskettes."

    ...and

    if($(code that returns a value/object) -eq "somevalue") { do_something }

    Is that all there is to subexpressions?  Because if it is, then that's easy.

     


    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".
    Friday, August 12, 2011 1:36 PM

Answers

  • Yes.

    $a = 1..15
    "The tenth number is $a[9]"
    "The tenth number is $($a[9])"


    The tenth number is 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15[9]
    The tenth number is 10


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    • Marked as answer by Bigteddy Friday, August 12, 2011 2:09 PM
    Friday, August 12, 2011 2:08 PM
  • Yep, it's that easy. Works for any expression that you want to evaluate inside an expandable string.

    EDIT: Btw, one nifty artifact of subexpressions is that you can include multiple statements in them, separated by semicolons.

    "Subexpression results: $($test = 55; 100/$test)"


    • Marked as answer by Bigteddy Friday, August 12, 2011 1:46 PM
    Friday, August 12, 2011 1:41 PM
  • Here's my best example so far:

     

    #Get % free space for drive that you enter...
    
    $c = gwmi -cl win32_logicaldisk -f "deviceid='$(Read-Host "Enter drive letter"):'" 
    "Percent free space for drive $($c.deviceid) equals $([System.Math]::Round($c.freespace / $c.size*100, 2))%"

    This really works.  I've tested it.

     


    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".
    • Marked as answer by Bigteddy Friday, August 12, 2011 6:30 PM
    Friday, August 12, 2011 6:30 PM

All replies

  • Yep, it's that easy. Works for any expression that you want to evaluate inside an expandable string.

    EDIT: Btw, one nifty artifact of subexpressions is that you can include multiple statements in them, separated by semicolons.

    "Subexpression results: $($test = 55; 100/$test)"


    • Marked as answer by Bigteddy Friday, August 12, 2011 1:46 PM
    Friday, August 12, 2011 1:41 PM
  • That's pretty much it. 

    Using a subexpression isn't hard, it's just a matter of knowing when it's required. 

     If it's an expression that has to be evaluated, as in your example, or a property of an object, an element of an array, or a value of a hash table entry, used in a double quoted string, it needs to be in a subexpression in order to get evaluated properly. 


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Friday, August 12, 2011 1:46 PM
  •  If it's an expression that has to be evaluated, as in your example, or a property of an object, an element of an array, or a value of a hash table entry, used in a double quoted string, it needs to be in a subexpression in order to get evaluated properly. 


    So if I understand correctly, what you're saying is:

    $a = 1..15 
    "The tenth number is $($a[9])"
    
    


    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".
    Friday, August 12, 2011 2:03 PM
  • Yes.

    $a = 1..15
    "The tenth number is $a[9]"
    "The tenth number is $($a[9])"


    The tenth number is 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15[9]
    The tenth number is 10


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    • Marked as answer by Bigteddy Friday, August 12, 2011 2:09 PM
    Friday, August 12, 2011 2:08 PM
  • Basically, within the string any character that represents a Powershell operator will be treated as a literal, except the sub-expression operator.

    see get-help about_operators

    Characters that represent Powershell operators that are within a sub-expression will be treated as Powershell operators, and the expression within the parens evaluated using those operators.

     

     


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Friday, August 12, 2011 2:30 PM
  • Cheers, mj.  That was lesson #2 for me today.  The first was calling WMI methods directly (chkdsk), because Ed Wilson published a cool function to get all WMI public methods, and I noticed that chkdsk was one of them for the win32_volume class.  One thing led to another, and the next thing I was calling chkdsk from a wmi object.  Quite cool.
    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".
    Friday, August 12, 2011 2:44 PM
  • I just had to do something useful with the $() subexpression thingy, just to make it really sink in.  See the following e.g., where I use it twice:

     

    #Get % free space for drive that you enter...
    
    $drive = Read-Host "Enter drive letter"
    $c = gwmi -Cl win32_logicaldisk -filter "deviceid='$($drive):'" 
    "Percent free space equals $($c.freespace / $c.size*100)%"
    

     


    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".

    Friday, August 12, 2011 5:28 PM
  • Cool. 

    Not  to rain on your parade, but while it does work $($drive) isn't really necessary.  There aren't any operators there, so $drive will work fine without the sub-expression.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Friday, August 12, 2011 5:33 PM
  • Yes, I realised that afterward, that's the whole point is to avoid the intermediate variable, so I modified it to this:

     

    #Get % free space for drive that you enter...
    
    $c = gwmi -Cl win32_logicaldisk -filter "deviceid='$(Read-Host "Enter drive letter"):'" 
    "Percent free space equals $($c.freespace / $c.size*100)%"
    

     In this case, surely, the $() is needed!

    That's only 2 lines for a whole 'application'. 


    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".

    • Marked as answer by Bigteddy Friday, August 12, 2011 6:12 PM
    • Unmarked as answer by Bigteddy Friday, August 12, 2011 6:29 PM
    Friday, August 12, 2011 5:48 PM
  •  In this case, surely, the $() is needed!

    It is indeed.  If you have any doubts, try the same command without it.
    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Friday, August 12, 2011 5:59 PM
  • Here's my best example so far:

     

    #Get % free space for drive that you enter...
    
    $c = gwmi -cl win32_logicaldisk -f "deviceid='$(Read-Host "Enter drive letter"):'" 
    "Percent free space for drive $($c.deviceid) equals $([System.Math]::Round($c.freespace / $c.size*100, 2))%"

    This really works.  I've tested it.

     


    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".
    • Marked as answer by Bigteddy Friday, August 12, 2011 6:30 PM
    Friday, August 12, 2011 6:30 PM