Expand string without Invoke-Expression

前端 未结 3 1272
忘了有多久
忘了有多久 2021-01-14 00:20

Imagine the following code:

# Script Start
$WelcomeMessage = \"Hello $UserName, today is $($Date.DayOfWeek)\"

..
..
# 100 lines of other functions and what          


        
3条回答
  •  星月不相逢
    2021-01-14 00:36

    Have you considered using a lambda expression; i.e. instead of defining the variable as a string value define it as a function, then invoke that function passing the relevant parameters at runtime.

    $WelcomeMessage = {param($UserName,$Date);"Hello $UserName, today is $($Date.DayOfWeek) $([void](remove-item c:\test\test.txt))"}
    
    #...
    # 100 lines of other functions and what not...
    #...
    
    "testfile" >> c:\test\test.txt #ensure we have a test file to be deleted
    
    function Get-UserNameFromSomewhereFancy(){return "myUsername";}
    function Get-DateFromSomewhereFancy(){return (get-date);}
    
    function Greet-User
    {
        $Username = Get-UserNameFromSomewhereFancy
        $Date = Get-DateFromSomewhereFancy
    
        $WelcomeMessage.invoke($username,$date)
    }
    
    cls
    Greet-User
    

    Update

    If you only wish to allow variable replacement the below code would do the trick; but this fails to do more advanced functions (e.g. .DayOfWeek)

    $WelcomeMessage = 'Hello $Username, today is $($Date.DayOfWeek) $([void](remove-item c:\test\test.txt))'
    #...
    # 100 lines of other functions and what not...
    #...
    
    "testfile" >> c:\test\test.txt #ensure we have a test file to be deleted
    
    function Get-UserNameFromSomewhereFancy(){return "myUsername";}
    function Get-DateFromSomewhereFancy(){return (get-date);}
    function Resolve-WelcomeMessage(){
        write-output {param($UserName,$Date);"$WelcomeMessage";}
    }
    function Greet-User
    {
        $Username = Get-UserNameFromSomewhereFancy
        $Date = Get-DateFromSomewhereFancy
        $temp = $WelcomeMessage 
        get-variable | ?{@('$','?','^') -notcontains $_.Name} | sort name -Descending | %{
            $temp  = $temp -replace ("\`${0}" -f $_.name),$_.value
        }
        $temp 
    }
    
    cls
    Greet-User
    

    Update

    To avoid code injection this makes use of -whatif; that will only help where the injected code supports the whatif functionality, but hopefully better than nothing...

    Also the code now doesn't require parameters to be declared; but just takes those variables which are available at the time of execution.

    $WelcomeMessage = {"Hello $Username, today is $($Date.DayOfWeek) $([void](remove-item c:\test\test.txt))"}
    
    #...
    # 100 lines of other functions and what not...
    #...
    
    function Get-UserNameFromSomewhereFancy(){return "myUsername";}
    function Get-DateFromSomewhereFancy(){return (get-date);}
    function Resolve-WelcomeMessage(){
        write-output {param($UserName,$Date);"$WelcomeMessage";}
    }
    
    "testfile" >> c:\test\test.txt #ensure we have a test file to be deleted
    
    function Greet-User {
        [cmdletbinding(SupportsShouldProcess=$True)]
        param()
        begin {$original = $WhatIfPreference; $WhatIfPreference = $true;}
        process {
            $Username = Get-UserNameFromSomewhereFancy
            $Date = Get-DateFromSomewhereFancy
            & $WelcomeMessage 
        }
        end {$WhatIfPreference = $original;}
    }
    
    cls
    Greet-User
    

提交回复
热议问题