【问题标题】:Powershell - Variable problemsPowershell - 变量问题
【发布时间】:2020-03-29 13:08:19
【问题描述】:

我编写了一个脚本,该脚本将从 .properties 文件(基本上是一个配置文件)中提取数据。属性文件中的一些数据具有环境数据(即 %UserProfile%),因此我通过一个将替换环境变量的函数 (Resolve–EnvVariable) 运行它与实际值。替换工作完美,但不知何故,数据似乎被改变了。 当我尝试使用通过函数运行的值时,它们不再起作用(见下面的结果)。

这是c:\work\test.properties的文件内容

types="*.txt"
in="%UserProfile%\Downloads"

这是我的 PowerShell 脚本

Clear-Host
#Read the properties file and replace the parameters when specified
if (Test-Path C:\work\test.properties) {
    $propertiesFile = Get-Content C:\work\test.properties
    Write-Host "Parameters will be substituded from properties file" -ForegroundColor Yellow
    foreach ($line in $propertiesFile) {
        Write-Host ("from Properties file $line")
        $propSwitch = $line.Split("=")[0]
        $propValue = Resolve–EnvVariable($line.Split("=")[1])
        switch ($propSwitch) {
            "types" { $types = $propValue }
            "in" { $in = $propValue }
        }
    }
}
write-host ("After running through function `n in=" + $in + "<-   types=" + $types + "<-")

# This function resolves environment variables
Function Resolve–EnvVariable {
    [cmdletbinding()]
    Param(
        [Parameter(Position = 0, ValueFromPipeline = $True, Mandatory = $True,
            HelpMessage = "Enter string with env variable i.e. %APPDATA%")]
        [ValidateNotNullOrEmpty()]
        [string]$String
    )

    Begin {
        Write-Verbose "Starting $($myinvocation.mycommand)"
    } #Begin

    Process {  
        #if string contains a % then process it
        if ($string -match "%\S+%") {
            Write-Verbose "Resolving environmental variables in $String"
            #split string into an array of values
            $values = $string.split("%") | Where-Object { $_ }
            foreach ($text in $values) {
                #find the corresponding value in ENV:
                Write-Verbose "Looking for $text"
                [string]$replace = (Get-Item env:$text -erroraction "SilentlyContinue").Value
                if ($replace) {
                    #if found append it to the new string
                    Write-Verbose "Found $replace"
                    $newstring += $replace
                }
                else {
                    #otherwise append the original text
                    $newstring += $text
                }

            } #foreach value

            Write-Verbose "Writing revised string to the pipeline"
            #write the string back to the pipeline
            Write-Output $NewString
        } #if
        else {
            #skip the string and write it back to the pipeline
            Write-Output $String
        }
    } #Process

    End {
        Write-Verbose "Ending $($myinvocation.mycommand)"
    } #End
} #end Resolve-EnvVariable


# Hardcoded values work
$test1 = Get-ChildItem -Path "C:\Users\Paul\Downloads" -Recurse -Include "*.txt" 

# Values pulled and updated through function do not work
$test2 = Get-ChildItem -Path $in -Recurse -Include $types 

# If I manually assign the values, it works
$in = "C:\Users\Paul\Downloads" 
$types = "*.txt"
$test3 = Get-ChildItem -Path $in -Recurse -Include $types 

foreach ($test in $test1) { write-host "test1 $test" }
foreach ($test in $test2) { write-host "test2 $test" }
foreach ($test in $test3) { write-host "test3 $test" }

结果

Parameters will be substituded from properties file
from Properties file types="*.txt"
from Properties file in="%UserProfile%\Downloads"
After running through function 
 in="C:\Users\Paul\Downloads"<-   types="*.txt"<-
test1 C:\Users\Paul\Downloads\Test\testPaul.txt
test1 C:\Users\Paul\Downloads\Test2\File1.txt
test3 C:\Users\Paul\Downloads\Test\testPaul.txt
test3 C:\Users\Paul\Downloads\Test2\File1.txt

【问题讨论】:

  • 您真正想要解决的问题是什么?请描述问题 - 而不是您认为需要解决问题的尝试解决方案。为什么不使用 Powershell 版本的环境变量,例如 $ENV:USERPROFILE
  • 我不知道你想在这里做什么。你能再澄清一下你的问题吗?

标签: powershell environment-variables


【解决方案1】:

两种选择:

1。使用Environment.ExpandEnvironmentVariables()

如果您切换到非限定字符串值并转义您的\,它就像将文件传送到ConvertFrom-StringData 一样简单,此时您可以使用Environment.ExpandEnvironmentVariables() 扩展变量值:

属性文件:

types=*.txt
in=%UserProfile%\\Downloads

脚本:

# Convert file to hashtable
$properties = Get-Content file.properties -Raw |ConvertFrom-StringData

# Copy value to new hashtable, but expand env vars first
$expanded = @{}
foreach($entry in $properties.GetEnumerator()){
    $expanded[$entry.Key] = [Environment]::ExpandEnvironmentVariables($entry.Value)
}

应该给你想要的值:

PS C:\> $expanded

Name                           Value
----                           -----
in                             C:\Users\username\Downloads
types                          *.txt

2。为您的属性使用和点源 PowerShell 脚本

这是直接从原始 Exchange Server 模块的页面中提取出来的 - 将所有配置变量放在单独的脚本中,这些脚本在初始化新会话时又是点源代码:

属性文件:

$types = "*.txt"
$in = Join-Path $env:USERPROFILE Downloads

脚本:

# dot source the variables
. (Join-Path $PSScriptRoot properties.ps1)

# do the actual work
Get-ChildItem $in -Include $types

【讨论】:

    猜你喜欢
    • 2021-11-18
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    相关资源
    最近更新 更多