不从本地计算机运行时,Powershell脚本输出错误的结果

时间:2017-04-10 20:42:41

标签: powershell powershell-v4.0

我最初在这里问过这个问题:Powershell script for checking AD replication这有助于解决我的脚本的逻辑问题。我已经在脚本中添加了其他信息和检查,最终结果如下:

function ExitWithCode {
<#
.SYNOPSIS
Specifies custom exit code. 

.DESCRIPTION
The ExitWithCode function allows you to pass in a custom exit code 
throughout your script by calling the function.

.PARAMETER
Use the -exitcode parameter followed by an integer to specify the error 
code

.EXAMPLE
Calling ExitWithCode -exitcode 2 will stop the powershell.exe process 
and report an exit code of 2 to the system.
#>

param
(
    $exitcode
)

$host.SetShouldExit($exitcode)
exit
}

function Write-Log {
<#
.SYNOPSIS
Write-Log writes a message to a logfile

.DESCRIPTION
The Write-Log function is designed to add logging capability to other 
scripts. In addition to writing output and/or verbose you can write to 
a log file for later debugging. 
#>

[CmdletBinding()]
Param
(
    [Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [Alias('LogContent')]
    [string]$Message,

    [Parameter(Mandatory = $false)]
    [ValidateSet("Error", "Info", "Status")]
    [string]$Level = "Info",

    [Parameter(Mandatory = $false)]
    [Alias('LogPath')]
    [string]$Path = ('C:\dataloop\ADHealthCheck\ADHealthCheck' + '_' + "$(Get-Date -Format MM-dd-yyyy)" + '.log'),

    [Parameter(Mandatory = $false)]
    [string]$logFolderPath = 'c:\dataloop\ADHealthCheck\'
)

BEGIN {

    [string]$FormattedDate = Get-Date -Format "dd-MM-yyyy HH:mm"

    #Test to see if the 'c:\dataloop\ADHealthCheck\' directory exist. If it does not, than create it.
    If (-NOT (Test-Path $logFolderPath)) {
        Write-Verbose "Creating the folder, $logFolderPath"
        New-Item $logFolderPath -Force -ItemType directory
    }

    #Test to see if the file 'c:\dataloop\ADHeatlhCheck\ADHealthCheck_{current_date}.log' exist. If it does not, than create it.
    If (-NOT (Test-Path $path)) {
        Write-Verbose "Creating $Path"
        [System.IO.FileInfo]$LogFile = New-Item $Path -Force -ItemType file
    }
}
PROCESS {   
    [string]$LogLine = "$FormattedDate - $Level - $message"
    $LogLine | Out-File -FilePath $Path -Append

    Switch ($Level) {

        "Info" {Write-Verbose $LogLine}
        "Status" {Write-Output $LogLine}
        "Error" {Write-Error $LogLine}
    }
}
END {}
}

function Get-ADHealthCheck {
[CmdletBinding()]
param()

BEGIN {
     Write-Log "Beginning the AD Health Check..."
}


PROCESS {
    #Obtain a list of all the domain controllers and sort them by name in ascedening order
    $DCs = Get-ADDomainController -Filter * |sort name

    Write-Log "$($DCs.Count) Domain Controllers found" -level Info

    #Create an empty array to store object properties later
    $results = @()

    ForEach ($DC in $DCs) {

        Write-Log "Getting replication metadata for $($DC.HostName)" -level Status

        #Grab replication metadata for each domain controller. Reports metadata for both inbound and outbound partners
        $ReplStatuses = Get-ADReplicationPartnerMetadata -target $DC.HostName -PartnerType Both -ErrorAction SilentlyContinue 

        If ($ReplStatuses) {

            #Reports the number of replication links found for each successful query
            Write-Log "$($ReplStatuses.Count) replication links found for $($DC.HostName)" -level Info

            ForEach ($ReplStatus in $ReplStatuses) {

                #Retrieves the hostname of each partner by splitting the 'Partner' key
                $Partner = $ReplStatus.Partner.Split(",")[1].Replace("CN=","")

                #create a custom object and set custom properties 
                $results += [pscustomobject] @{
                    'Source DC' = $DC.Hostname.ToUpper()
                    'Partner DC' = (Get-ADComputer $Partner).DNSHostName.ToUpper()
                    'Direction' = $ReplStatus.PartnerType
                    'Type' = $ReplStatus.IntersiteTransportType
                    'Last Attempt' = $ReplStatus.LastReplicationAttempt
                    'Last Success' = $ReplStatus.LastReplicationSuccess
                    'Last Result' = $ReplStatus.LastReplicationResult
                }
            }   
        }

        Else {

            #creates a custom object to store information about any domain controller where replication data could not be retrieved
            Write-Log "Unable to get replication status for $($DC.HostName)" -level Error
            $results += [pscustomobject] @{
                'Source DC' = $DC.Hostname.ToUpper()
                'Partner DC' = "N/A"
                'Direction' = "N/A"
                'Type' = "N/A"
                'Last Attempt' = "N/A"
                'Last Success' = "N/A"
                'Last Result' = "N/A"
            }

        }
    }

    #Start checking for outdated log files to purge
    Write-Log "Cleaning out outdated Log files..."

    #Define the log path
    $logPath = 'c:\dataloop\ADHealthCheck\'

    #Do the actual check based on the log path defined above
    $checkLogPath = Get-ChildItem -Path $logPath -Recurse

    #Performs check against the log path and returns any files where the last modified date is greater than 14 days
    $retentionPeriod = $checkLogPath | Where {$_.LastWriteTime -lt (Get-Date).AddDays(-14)}

    foreach ($file in $retentionPeriod) {
        if ($retentionPeriod) {
            Write-Log "Deleting file $file since it is older than 14 days" -Level Info

            #Sets the current working directory to the log path
            Set-Location $logPath

            #Deletes any files where the modified date is greater than 14 days
            Remove-Item $file -Force
        }

        else {
            Write-Log "There were no files older than two weeks. Nothing to delete at this time" -Level Info
        }
    }

    #Check to see if any of the results contain failure
    $failedChecks = $results | Where-object{$_.'Last Result' -ne 0}

    #Evaluate $failedChecks as a boolean. If there are no failed checks Else can be assumed that everything is fine. 
    If ($failedChecks) {
        Write-Log "These domain controllers have replication errors. Please review them..." -Level Error
        $error = $failedChecks | select 'Source DC','Partner DC','Direction' | ft -AutoSize | Out-String
        Write-Log $error -Level Error
        ExitWithCode -exitcode 2        
    } 

    Else {
        Write-Log "There were no replication issues found" -Level Info
        ExitWithCode -exitcode 0 
    }
  }
}

Get-ADHealthCheck

脚本似乎没有任何问题。当我在服务器上本地运行它来测试时,一切正常。它在正确的目录中创建具有正确名称的正确日志文件。我检查了日志消息,然后全部检查出来。

问题是当我尝试将脚本作为插件移植到Dataloop / Outlyer并将其设置为在特定服务器上运行时,脚本本身会将正确的状态输出到Dataloop但是如果我然后远程进入运行脚本的服务器并且检查我的日志文件,即使命令成功运行,它也会记录所有错误消息。

有没有人看到过这样的问题,其中脚本运行并在本地正确报告但是当由代理触发时,它会记录所有错误的信息?我也接触过Dataloop的支持,但我也在这里查看。

1 个答案:

答案 0 :(得分:0)

对于那些感兴趣的人,dataloop-agent服务在安装期间创建的内置dataloop-agent用户下运行,并且没有管理员权限。

修复方法是简单地将服务更改为在本地系统用户下运行。您可以通过GUI手动完成,也可以使用批处理脚本自动完成。