代我更改函数参数值不加修改 [英] Function parameter value changing without modification on my behalf

查看:47
本文介绍了代我更改函数参数值不加修改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个 powershell 新手,目前遇到了一个愚蠢的问题(至少对我来说),我会尽力在下面解释.

I'm a powershell novice and am currently encountering a goofy issue (to me at least) that I'll try my best to explain below.

我遇到了一个问题,即函数参数的先前值在下次调用该函数时被前置"到同一参数.该函数的那个​​或我的两个参数正在组合,并且正在发生我不知道的其他事情.单步调试 ISE 调试器无助于解决此问题.我将输入我的代码和我正在阅读的文本文件,然后在下面进一步解释这个问题.

I'm having issues with what seems to be prior values for a function parameter being "pre-pended" to that same parameter the next time that function is called. That or my two parameters for the function are being combined and something else is occurring that I'm not aware of. Stepping through the ISE debugger has not helped with solving this issue. I'll throw in my code and the text files that I am reading from then explain the issue further below.

[CmdletBinding()]
Param(
    #Path to file containing weak ACL's before software installation
    [Parameter(Mandatory = $false)] [string]$BeforeInstallACL = "./Before.txt", 

    #Path to file containing weak ACL's after software installation
    [Parameter(Mandatory = $false)] [string]$AfterInstallACL = "./After.txt",

    #Folder location of output file
    [Parameter(Mandatory = $false)] [string]$OutputPath = "./"
)

$latestRegPath = $null

function ReadFromBeforeInstallation ($line, $newRegisteryItem) {
    # Checks if the param (file, dir, or registery key path) exists in $BeforeInstallACL 
    $regItem = $newRegistryItem
    $isPath = CheckIfPath($line)
    Write-Host $line
    $pathFound = $false
    if ($isPath) {
        $content = Get-Content $BeforeInstallACL
        $content | ForEach-Object {
            if ($_.ToString().Trim() -eq $line) {
                $pathFound = $true
                break
            }
       }
       if (!$pathFound) {
           # We have a path that only showed up after installation and want to output this
           $regItem = $line
           WriteToOutput("`r`n{0}`r`n" -f $regItem)
       }
   }
   return $regItem
}

function ReadFromAfterInstallation {
    $content = Get-Content $AfterInstallACL
    $newRegistryItem = $null
    $content | ForEach-Object {
        $_ = $_.Trim()
        if ($_) {
            if ($newRegistryItem) {
                WriteToOutput($_)
            }
            $newRegistryItem = ReadFromBeforeInstallation($_, $newRegistryItem)
        }
        else {
            $newRegistryItem = $null
        }
    }            
}

function WriteToOutput {
    param (
        # Line of a File, Dir or Registery Key from $AfterInstallACl
        [Parameter(Mandatory=$true, Position=0)]
        [string] $Line
    )
    $Line | Out-File -FilePath $OutputFile -Append
}

function CheckIfPath($line) {
    # Check if the line paramater is a path or not
    $isMatch = $false
    if ($line -match "HKEY_LOCAL_MACHINE") {
        $isMatch = $true
    }
    return $isMatch
}

#Create the empty output file we're going to use for logging
$OutputFile = Join-Path -Path $OutputPath -ChildPath difference_output.txt
New-Item $OutputFile -type File -force >$null


Get-Date | Out-File -FilePath $OutputFile 
ReadFromAfterInstallation
Get-Date | Out-File -FilePath $OutputFile -Append

这是after.txt

Here is after.txt

Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DRM
Everyone
SetValue, CreateSubKey, CreateLink, ReadKey, ChangePermissions, TakeOwnership


Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Function Discovery\RegistryStore\Publication\Explorer
Everyone
SetValue, CreateSubKey, ReadKey
BUILTIN\Users
SetValue, CreateSubKey, ReadKey


Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Input\HwkSettings
BUILTIN\Users
SetValue, CreateSubKey, ReadKey

这里是before.txt

and here is before.txt

Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Function Discovery\RegistryStore\Publication\Explorer
Everyone
SetValue, CreateSubKey, ReadKey
BUILTIN\Users
SetValue, CreateSubKey, ReadKey


Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Input\HwkSettings
BUILTIN\Users
SetValue, CreateSubKey, ReadKey


Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Input\Locales
BUILTIN\Users
SetValue, CreateSubKey, ReadKey


Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Input\Locales\loc_0039
BUILTIN\Users
SetValue, CreateSubKey, ReadKey

问题出在 ReadFromBeforeInstallation() 中,它在 ReadFromAfterInstallation() 中调用.在 ReadFromAfterInstallation 中,我遍历 after.txt 的行,将它们传递给 ReadFromBeforeInstallation,然后查看该行是否包含HKEY_LOCAL_MACHINE".如果是这样,并且该行在 before.txt 中不存在,我想将该行写入我的输出文件.

The issue is in ReadFromBeforeInstallation() which is called in ReadFromAfterInstallation(). In ReadFromAfterInstallation, I am iterating through the lines of a after.txt, passing them to ReadFromBeforeInstallation and then seeing if the line contains "HKEY_LOCAL_MACHINE". If so, and that line is not present in before.txt, I want to write the line to my output file.

听起来很简单.我只是想找到在after.txt 中而不是before.txt 中的HKLM 注册表项.我注意到 ReadFromBeforeInstallation 中的 $line 参数保存了过去函数调用的结果.一个简单的 Write-Host 语句将显示如下所示的行

Sounds simple enough. I'm just trying to find the HKLM registry keys that are in after.txt but not before.txt. What I noticed was that the $line param in ReadFromBeforeInstallation was holding results from past functional calls. A simple Write-Host statement would show lines like the following

Everyone Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DRM
SetValue, CreateSubKey, ReadKey Everyone Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Function Discovery\RegistryStore\Publication\Explorer 

我从未在 after.txt 中出现过这样的行.当程序运行时,将鼠标悬停在 ISE 中 ReadFromBeforeInstallation 中的 $line 参数上显示 $line 也是它应该是什么,但是一旦我到达 CheckifPath() 调用它就会附加一个 HKEY 路径.我真的很难过这里会发生什么.我意识到这是一篇很长的文章,但如果有人能帮助我,我将不胜感激.

I never had lines like this in after.txt. Hovering over the $line parameter in ReadFromBeforeInstallation in ISE when the program was running showed that $line was what it was supposed to be too but it once I reached CheckifPath() call it would have an HKEY path appended to it. I'm really stumped what could be going on here. I realize this was a long post, but if anyone could help me out, I would greatly appreciate it.

顺便说一句,我的 powershell 版本是 5.1

btw, my powershell version is 5.1

推荐答案

您使用了错误的调用语法

You're using the wrong invocation syntax

改变这个:

ReadFromBeforeInstallation($_, $newRegistryItem)

为此:

ReadFromBeforeInstallation $_ $newRegistryItem
# or
ReadFromBeforeInstallation -line $_ -newRegisteryItem $newRegistryItem

否则,PowerShell 会将表达式 ($_, $newRegistryItem) 解释为 1 个参数并将其仅绑定到函数的第一个位置参数!

Otherwise, PowerShell will interpret the expression ($_, $newRegistryItem) as 1 argument and bind that only to the first positional parameter of the function!

以下帮助主题可能有助于更好地理解 PowerShell 的命令调用语法:

The following help topics might be useful in understanding PowerShell's command invocation syntax better:

这篇关于代我更改函数参数值不加修改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆