Powershell v2 | 脚本无法声明变量,需要帮助调试

3

好的,似乎脚本有几个问题,我无法解决其中任何一个,还希望能对脚本进行一些反馈。这仍然是我的第一个脚本,所以可能需要很多小调整,请告诉我您想到的任何建议。

问题:大部分问题都围绕着日志记录。

  1. 没有检查日志文件,因此脚本会一遍又一遍地将计算机添加到日志文件中。

  2. 日志文件不更新生成的信息,例如操作系统、mac、ip等。

显示的问题:

无法在此对象上找到属性“Result”。确保它存在。位于 W:\Powershell Scripting\Test Lab\TestFunction.ps1:86 字符:17 + IF ($Computer. <<<< Result -ne "Successful") { + CategoryInfo : InvalidOperation: (.:OperatorToken) [], RuntimeException + FullyQualifiedErrorId : PropertyNotFoundStrict

脚本:

Set-PSDebug -strict
Set-StrictMode -Version latest
$consoleObject = (Get-Host).UI.RawUI

# Adjustable Variables
$Computers_Path = ".\computers.txt"
$Log_Path = ".\Log.txt"
$Log_MaxTick = 5
$RunOnServers = 0

# Multi-Threading Variables
$Jobs_MaxAtOnce = 20
$SleepTimer = 500

# Script Specific Variables
$ScriptTitle = "Local Admin Check"

# Validate Adjustable Variables
$Computers = @(Import-CSV $Computers_Path -header "Name","MAC")

# Framework Specific Variables (Pre-Setting Variables)
$Run = 0; $Succssful = 0; $Jobs_Count = 0; $Log_Tick= 0; $WriteToLog = "No"

# Misc
$Total = $Computers.length
IF (!(Test-Path $Log_Path)) { Add-Content $Log_Path "Name,OS,Mac,IPAddress,Status,Attempts,Result,LastAttempt" }
$Log = @(Import-Csv $Log_Path)
$Successful = ($Log | Where-Object {$_.Result -eq "Successful"} | Select-String -inputobject {$_.Name} -pattern $Computers | Measure-Object).Count

# Load Functions
Function GetOS {
    $RegCon = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer.Name )
    $RegKey = $RegCon.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\")
    $RegValue = $RegKey.GetValue("ProductName")
    $RegCon.Close()
    $Computer.OS = $RegValue
}

Function SmartLogging {

    If ($Args[0] -eq "AddComputer") {
        Add-Content ($Computer.Name + "," + $Computer.OS + "," + $Computer.Mac + "," + $Computer.IPAddress + "," + $Computer.Status + "," + $Computer.Attempts + "," + $Computer.Result + "," + $Computer.LastAttempt) -path .\log.txt
    } ELSEIF ( $Log_Tick -eq $Log_MaxTick -OR $Args -eq "Update" ) {
        $Log_Tick = 0;
        Get-Content $Log_Path | Foreach-Object {$_ -replace "$Computer.Name,.*", ($Computer.Name + "," + $Computer.OS + "," + $Computer.Mac + "," + $Computer.IPAddress + "," + $Computer.Status + "," + $Computer.Attempts + "," + $Computer.Result + "," + $Computer.LastAttempt)} | Set-Content $Log_Path
    } ELSEIF ($Args[0] -eq "CheckComputer") {
         IF (!($Log | Select-String -pattern $Computer.Name -SimpleMatch)) {
            $Log += New-Object PSObject -Property @{ Name = $Computer.Name; OS = $NULL; Mac = $Computer.MAC; IPAddress = $NULL; Status = $NULL; Attempts = 0; Result = $NULL; LastAttempt = $NULL;}
            $Computer = $Log | Where-Object {$_.Name -eq $Computer.Name}
            SmartLogging AddComputer
        } ELSE {
            $Computer = $Log | Where-Object {$_.Name -eq $Computer.Name}
        }
    } ELSEIF (-not $Args[0]) {
        "Log Ticked"
        $Log_Tick++
    }
}

Function GetIPAddress {
    $IPAddress = [System.Net.Dns]::GetHostAddresses("TrinityTechCorp") | Where-Object {$_.IPAddressToString -like "*.*.*.*"};
    $Computer.IPAddress = $IPAddress.IPAddressToString
}

Function WindowTitle {
    [int]$Successful_Percent = $Successful / $Total * 100
    $consoleObject.WindowTitle = “$ScriptTitle - $Successful Out Of $Total ($Successful_Percent%) Successful `| Run`: $Run”
}

# Start Script
while ( $Successful -le $Total ) {
    $Run++
    ForEach ($Computer in $Computers) {
        WindowTitle 
        SmartLogging CheckComputer
        IF ($Computer.Result -ne "Successful") {
            IF (test-connection $Computer.Name -quiet ) {
                $Computer.Status = "Awake"
                IF (!$Computer.OS){GetOS}
                IF (!$Computer.IPAddress){GetIPAddress}
                ## Start Script ##
                    $CheckComputer = [ADSI]("WinNT://" + $Computer.Name + ",computer")
                    $Group = $CheckComputer.psbase.children.find("Administrators")
                    $members= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
                    ForEach($user in $members) {
                        $Result = $Computer.Name + "," + $user.ToString()
                        Add-Content $Result -path .\Result.csv
                    }
                ## End Script ##
                SmartLogging Update
                $Computer.Result = "Successful"
                $Successful += 1
            } ELSE {
                $Computer.Status = "Unknown"
            }
            $Computer.Attempts = [int] $Computer.Attempts + 1
            $Computer.LastAttempt = Get-Date -uFormat "%I:%M:%S%p %d%b%y"
        }
    SmartLogging
    }
}
Write-Output "Script Completed"

2
代码太多了。你可能想要减少样本的数量,使其小到可以轻松地再现出你所遇到的问题。 - Victor Zakharov
2个回答

1
这次的问题是您在$Computers集合成员中没有Result成员,只有NameMAC。除非您稍后在代码中添加此成员,但我不想阅读它,因为它已经有大约100行,并且包含与实际问题陈述无关的很多代码。
$Computers = @(Import-CSV $Computers_Path -header "Name","MAC")

你尝试过在Powershell ISE上调试脚本吗?它是Powershell 2的内置调试器。可以看一下Technet文章了解更多信息。


作为 PS ISE 的替代方案,您可以使用 PowerGUI 脚本编辑器进行调试。它在 v2 上运行良好。 - Victor Zakharov

1

这是关于 $Computers 集合的声明...

$Computers = @(Import-CSV $Computers_Path -header "Name","MAC")

...在这种情况下无法工作:

IF ($Computer.Result -ne "Successful")

异常消息明确指出了问题所在:

对象上找不到属性'Result'。请确保该属性存在。\TestFunction.ps1:86 char:17

为解决此问题,建议初始化Result属性,可能需要这样做:

$Computers = @(Import-CSV $Computers_Path -header "Name","MAC","Result")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接