Powershell Power Shell获取子项,然后通过管道获取内容

Powershell Power Shell获取子项,然后通过管道获取内容,powershell,file-get-contents,get-childitem,Powershell,File Get Contents,Get Childitem,我正在尝试检索已知文件名的未知文件路径,然后对该文件名执行获取内容,以便修改它。我知道该文件将位于C:\Users\$env:UserName\中,但这是我所能做的(最终用户可能会将其放在其他位置,如文档或桌面或其他位置) 它似乎可以执行Get ChildItem或Get Content操作,但由于某些原因,我无法在同一个脚本中同时执行这两个操作 总体目标:通过管道将Get ChildItem的结果传递到Get Content函数,以便我可以修改文件。 这是我的密码: (Get-ChildIte

我正在尝试检索已知文件名的未知文件路径,然后对该文件名执行
获取内容
,以便修改它。我知道该文件将位于
C:\Users\$env:UserName\
中,但这是我所能做的(最终用户可能会将其放在其他位置,如文档或桌面或其他位置)

它似乎可以执行
Get ChildItem
Get Content
操作,但由于某些原因,我无法在同一个脚本中同时执行这两个操作

总体目标:通过管道将Get ChildItem的结果传递到Get Content函数,以便我可以修改文件。

这是我的密码:

(Get-ChildItem -Path C:\Users\$env:UserName -Filter QA11test.hep) | 
    Foreach-Object {
        $_ # send the current line to output
        if($_ -match "SSL/TLS User Cipher Suites=DEFAULT"){
            "IP Port=2023"
            "Security Option=2"
            $Message = "Your host explorer session has been updated."
            Msg $env:UserName $Message
            exit
        } else {
            $Message = "Script Failed."
            Msg $env:UserName $Message
            exit
        }
    } | Set-Content C:\Users\$env:UserName\Telnet\QA11TestSecure.hep

需要帮助!谢谢大家!

对于如何获取文件及其内容,然后检查文件内容中的任意行,似乎存在一些混淆。我建议不要把它写在一个大的复合命令中,而是将它分解成不同的样式,这样可以最大限度地减少管道混乱。有几种方法可以完成相同的任务,有些方法比其他方法更容易遵循,特别是在调试时

$fileoutput = @'
IP Port=2023
Security Option=2
'@
$FileToLookAt = Get-ChildItem -Path C:\Users\$env:UserName -Recurse -Filter "QA11test.hep" | Get-Content
if ($FileToLookAt)
{
    $found = ""
    $found = $FileToLookAt | Where-Object {$_ -eq 'SSL/TLS User Cipher Suites=DEFAULT'}
    if ($found)
    {
        $Message = "Your host explorer session has been updated."
        Set-Content -Path C:\Users\$env:UserName\Telnet\QA11TestSecure.hep -Value $fileoutput -Force
    } else 
    {
        $Message = "Script Failed."
    }
} else 
{
    $Message = "QA11test.hep not found."
}
Msg $env:UserName $Message

编辑:好的,确实应该检查集合内容以确保文件/路径存在。假设是这样的话,类似的方法应该可以工作。

在最简单的情况下,您只需使用
Get Content
命令插入一个管道段:

Get-ChildItem -Path C:\Users\$env:UserName -Filter QA11test.hep |
  Get-Content | # Send the lines of the input file(s) one by one to ForEach-Object
    ForEach-Object { ...
但是,您的方法存在问题:

  • 如果找到文件,则无条件写入输出文件-即使未对输入内容进行任何修改

    • 此外,由于代码中的
      exit
      语句,输出文件中会省略所有剩余的输入行
  • 如果未找到文件,则输出文件将创建为空文件(
    0
    bytes),或者,如果已存在,则替换为空文件


相反,我建议使用基于的方法,该方法更快、更简洁、更灵活:

值得注意的是,此解决方案仅在找到输入文件并对其进行修改时创建/替换输出文件

Get-ChildItem -Path C:\Users\$env:UserName -Filter QA11test.hep | ForEach-Object {
  $updated = $false
  $newLines = switch -File $_.FullName -Regex { # Loop over all file lines
    'SSL/TLS User Cipher Suites=DEFAULT' { 
       $_, "IP Port=2023", "Security Option=2" # send 2 additional lines
       $updated = $true
    }
    default { $_ } # pass other lines through
  }
  # Rewrite the file only if modifications were made.
  if ($updated) { $newLines | Set-Content C:\Users\$env:UserName\Telnet\QA11TestSecure.hep }
  # Emit the appropriate status message.
  Msg $env:UserName ('Nothing to update.', 'Your host explorer session has been updated.')[$updated]
}
注意:如果您还需要知道是否找到了输入文件-无论是否需要更新-在脚本块内设置
$found=$true
,并在命令后检查它:
If(-not$found){Msg$env:UserName'QA11test.hep not found'}

  • switch-File$\ FullName-Regex
    逐行读取输入文件,并根据Regex条件匹配每一行:

    • 如果正则表达式匹配,则输出原始行(
      $
      )以及另外两行;另外,设置标志
      $updated
      ,指示内容已修改
    • 所有其他行(默认的条件行)按原样输出
  • $newLines=…
    捕获数组中的(可能修改的)行

    • 请注意,这意味着所有行一次存储在内存中,但文本文件通常不受关注
  • 仅当设置了
    $updated
    时,才会写入输出文件(
    设置内容

  • 最后,调用
    Msg
    命令时会显示相应的状态消息

    • 请注意
      ('msg1','msg2')[$updated]
      表达式,它是根据标志从两个值中选择一个值的快捷方式:如果
      $updated
      $true
      $true
      被强制到数组索引
      1
      ,因此选择
      'msg2'
      ;如果为
      $false
      ,则索引为
      0
      ,并选择
      'msg1'

    • 感谢所有帮助过你的人

      (@mklement0,我将修改此内容,使其与您上一篇文章的内容接近!这对我有很大帮助。)

      我从不同的帖子中找到了一些零碎的东西,这就是我所想到的,我需要它来做的

      此PowerShell脚本获取已知文件“QA11test.hep”的完整路径,并将其加载到变量中供以后使用。然后,它在该文件的内容中搜索特定字符串“SSL/TLS..etc”,如果找到它,它会在找到的行下面添加两行,“Port=2023”和“Security Option 2”。然后,它获取新文件并将其添加到C:\Users\$env:UserName\Desktop\QA11TestSecure.hep,而不更改原始的QA11test.hep文件。因此,它将从get-childitem函数检索到的项放入一个变量中,然后get-content函数可以搜索该变量,而不是从get-childitem到get-content的管道。很好

      $FileToLookAt = (Get-ChildItem -Path C:\Users\$env:UserName\ -Recurse -Filter "QA11test.hep") | % { $_.FullName }
      $User = $env:UserName
      if ($FileToLookAt){
          $updated = $false
          $addtls = Get-Content ($FileToLookAt) | Foreach-Object {
              $_ # send the current line to output
              if($_ -match "SSL/TLS User Cipher Suites=DEFAULT"){
                  "IP Port=2023"
                  "Security Option=2"
                  $updated = $true
              }
          }
          if ($updated) {
              $addtls | Set-Content -Path C:\Users\$env:UserName\Desktop\QA11TestSecure.hep
              $Message = "Host Explorer updated.`nPlease ensure there is a gold LOCK icon at the bottom left `nof the host explorer window.`nIf not, please contact the help center. Thank you."
          } else {
              $message = "File was not updated.`nPlease contant the help center immediatly."
          }
      } else {
          $Message = "QA11test.hep not found.`nPlease contact the helpdesk immediately."
      }
      Msg $env:UserName $Message
      exit
      

      我正在将“IP端口=2023”和“安全选项=2”写入该文件。当您说写入该文件时,我假设您不是指附加。我是指插入该文件。您上面的代码工作得非常好!谢谢,但问题是它将这两行放在了文件的顶部。我需要在带有“SSL/TLS用户…”的行之后插入这些行,以便我在您希望添加行的单独文件中读取,插入行并写出文件的新版本,看看这个类似问题的答案:正确的做法是与那些回答问题的人合作,让他们的答案对你和未来的读者都有帮助。我刚刚测试了我的代码,它工作了-请详细告诉我您认为switch语句中的错误是什么-我总是很乐意更正我的答案。根据你提出的问题,我看不出丢失了什么关键部件。同样,在现实生活中,你最终需要的解决方案的细节在这里是无关紧要的,在你的答案中向代码中添加额外的位只会让人困惑。重新投票:谢谢你的尝试。一旦你达到15分,你的投票数将被计算在内(我已经对你的问题投了赞成票)。也谢谢你的解释。我知道你的代码做了什么