Powershell pitfalls

后端 未结 21 1192
梦谈多话
梦谈多话 2020-12-23 01:44

What Powershell pitfalls you have fall into? :-)

Mine are:

# -----------------------------------
function foo()
{
    @(\"text\")
}

# Expected 1, a         


        
相关标签:
21条回答
  • 2020-12-23 02:16

    Another one:

    $x = 2
    $y = 3
    $a,$b = $x,$y*5 
    

    because of operators precedence there is not 25 in $b; the command is the same as ($x,$y)*5 the correct version is

    $a,$b = $x,($y*5)
    
    0 讨论(0)
  • 2020-12-23 02:16

    This works. But almost certainly not in the way you think it's working.

    PS> $a = 42;
    PS> [scriptblock]$b = { $a }
    PS> & $b
    42
    
    0 讨论(0)
  • 2020-12-23 02:16

    Treating the ExitCode of a Process as a Boolean.

    eg, with this code:

    $p = Start-Process foo.exe -NoNewWindow -Wait -PassThru
    if ($p.ExitCode) {
      # handle error
    }
    

    things are good, unless say foo.exe doesn't exist or otherwise fails to launch. in that case $p will be $null, and [bool]($null.ExitCode) is False.

    a simple fix is to replace the logic with if ($p.ExitCode -ne 0) {}, however for clarity of code imo the following is better: if (($p -eq $null) -or ($p.ExitCode -ne 0)) {}

    0 讨论(0)
  • 2020-12-23 02:17

    Another one I ran into recently: [string] parameters that accept pipeline input are not strongly typed in practice. You can pipe anything at all and PS will coerce it via ToString().

    function Foo 
    {
        [CmdletBinding()]
        param (
            [parameter(Mandatory=$True, ValueFromPipeline=$True)]
            [string] $param
        )
    
        process { $param }
    }
    
    get-process svchost | Foo
    

    Unfortunately there is no way to turn this off. Best workaround I could think of:

    function Bar
    {
        [CmdletBinding()]
        param (
            [parameter(Mandatory=$True, ValueFromPipeline=$True)]
            [object] $param
        )
    
        process 
        { 
            if ($param -isnot [string]) {
                throw "Pass a string you fool!"
            }
            # rest of function goes here
        }
    }
    

    edit - a better workaround I've started using...

    Add this to your custom type XML -

    <?xml version="1.0" encoding="utf-8" ?>
    <Types>
      <Type>
        <Name>System.String</Name>
        <Members>
          <ScriptProperty>
            <Name>StringValue</Name>
            <GetScriptBlock>
              $this
            </GetScriptBlock>
          </ScriptProperty>
        </Members>
      </Type>
    </Types>
    

    Then write functions like this:

    function Bar
    {
        [CmdletBinding()]
        param (
            [parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)]
            [Alias("StringValue")]
            [string] $param
        )
    
        process 
        { 
            # rest of function goes here
        }
    }
    
    0 讨论(0)
  • 2020-12-23 02:19

    Here are my top 5 PowerShell gotchas

    0 讨论(0)
  • 2020-12-23 02:19

    Remembering to explicitly type pscustom objects from imported data tables as numeric so they can be sorted correctly:

    $CVAP_WA=foreach ($i in $C){[PSCustomObject]@{ `
                    County=$i.county; `
                    TotalVote=[INT]$i.TotalBallots; `
                    RegVoters=[INT]$i.regvoters; `
                    Turnout_PCT=($i.TotalBallots/$i.regvoters)*100; `
                    CVAP=[INT]($B | ? {$_.GeoName -match $i.county}).CVAP_EST }}
    

    PS C:\Politics> $CVAP_WA | sort -desc TotalVote |ft -auto -wrap

    County       TotalVote RegVoters Turnout_PCT    CVAP CVAP_TV_PCT CVAP_RV_PCT
    ------       --------- --------- -----------    ---- ----------- -----------
    King            973088   1170638      83.189 1299290      74.893      90.099
    Pierce          349377    442985       78.86  554975      62.959      79.837
    Snohomish       334354    415504      80.461  478440      69.832       86.81
    Spokane         227007    282442      80.346  342060      66.398      82.555
    Clark           193102    243155      79.453  284190      67.911       85.52
    
    0 讨论(0)
提交回复
热议问题