繁体   English   中英

如何使用填充有路径的变量在PowerShell中导航或执行?

[英]How can I use a variable filled with a path to navigate or execute in PowerShell?

我当前是第一次编写PowerShell脚本。 我只想找出Windows机器上运行的Java版本。 它正在搜索所有java.exe实例,将其写入文件中,然后应执行每一行并将输出写入文件中。 但是我不能使用变量$command执行任何操作。 因此,由于错误, for循环仅运行一次,然后退出。

#declaration
$file = ".\text.txt"
$i = 3
$out = ".\output.txt"

Get-ChildItem -Path C:\ -Filter java.exe -Recurse -ErrorAction SilentlyContinue -Force |
    Select-Object Directory >> $file
$count = Get-Content $file | Measure-Object -Line

#remove spaces and append "java.exe"
(Get-Content $file | Foreach {$_.TrimEnd()}) | Set-Content $file
(Get-Content $file | foreach {$_ + "\java.exe' -version"}) | Set-Content $file
(Get-Content $file).Replace("C:", "'C:") | Set-Content $file

#remove last 2 lines of the file
$count = $count.Lines - 2

#execute the stored paths

$i = 3
for ($i=3; $i -le $count; $i++) {
    $command = Get-Content $file | Select -Index $i;
    $command >> $out;
    & $command 2> $out;   # <----------------This line wont work
    echo "_____________________" >> $out;
}

尽管我不确定所需的输出是什么样,但是下面创建了一个PSObjects数组,您可以在屏幕上输出或将其写入CSV文件。

$result = Get-ChildItem -Path C:\ -Filter java.exe -File -Recurse -ErrorAction SilentlyContinue -Force | ForEach-Object {
    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = $_.FullName
    $pinfo.Arguments = "-version"
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $process = New-Object System.Diagnostics.Process
    $process.StartInfo = $pinfo
    $process.Start() | Out-Null
    $process.WaitForExit()
    $output = $process.StandardOutput.ReadToEnd()
    if (!$output) { $output = $process.StandardError.ReadToEnd() }
    [PsCustomObject]@{
        'FileName'    = $_.FullName
        'VersionInfo' = $output
    }
}
# output on screen
$result | Format-List

# output to CSV file (VersionInfo field uses multiple lines)
$result | Export-Csv -Path 'D:\javaversions.csv' -UseCulture -NoTypeInformation

屏幕上的结果看起来像:

 FileName : C:\\Program Files\\Java\\jdk1.8.0_31\\bin\\java.exe VersionInfo : java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode) FileName : C:\\Program Files\\Java\\jdk1.8.0_31\\jre\\bin\\java.exe VersionInfo : java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode) FileName : C:\\Program Files\\Java\\jre1.8.0_221\\bin\\java.exe VersionInfo : java version "1.8.0_221" Java(TM) SE Runtime Environment (build 1.8.0_221-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode) 

@Theo的替代解决方案是使用一个临时文件,如下所示:

$GetParams = @{
    Path        = 'C:\'
    Filter      = 'java.exe'
    Recurse     = $true
    Force       = $true
    File        = $true
    ErrorAction = 'SilentlyContinue'
}
$JavaExeFiles = Get-ChildItem @GetParams | select -First 1

$StartParams = @{
     ArgumentList          = '-version'
     NoNewWindow           = $true
     RedirectStandardError = '.\javaver.txt'
}

$JaveExeDetails = foreach ($JaveExe in $JavaExeFiles) {
    Remove-Item -Path $StartParams.RedirectStandardError -EA Ignore

    Start-Process @StartParams -FilePath $JaveExe.FullName -Wait

    [PSCustomObject]@{
        File    = $JaveExe.FullName
        Version = Get-Content -Path $StartParams.RedirectStandardError
    }
}

# For viewing in the console
$JaveExeDetails | fl *

# For export to a file
$JaveExeDetails | fl * | Out-File -FilePath ./JavaVersions.txt

您的代码无效,因为您要将整个命令行写入中间文件,然后尝试通过调用运算符从该文件中调用命令字符串。 这不起作用,因为命令"'C:\\path\\to\\java.exe' -version"不存在。 您应该得到这样的错误:

PS C:\> $command = "'C:\path\to\java.exe' -version"
PS C:\> & $command
& : The term ''C:\path\to\java.exe' -version' is not recognized as the name of
a cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
At line:1 char:3
+ & $command
+   ~~~~~~~~
    + CategoryInfo          : ObjectNotFound: ('C:\path\to\java.exe' -version:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

使代码正常工作的最简单方法是直接调用可执行文件:

Get-ChildItem -Path 'C:\' -Filter 'java.exe' -Recurse -EA SilentlyContinue -Force |
    ForEach-Object {
        $_.FullName + ' -version'
        & $_.FullName -version 2>&1
        '__________________'
    } |
    Set-Content $out

如果您想使用中间文件来使用该方法,则需要在命令行之前添加调用运算符,将其转换为脚本块,然后调用该脚本块。

Get-Content $file | ForEach-Object {
    $command
    & ([Scriptblock]::Create("& $command")) 2>&1
    '__________________'
} | Out-File $out

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM