2017-04-10 3 views
0

원래이 질문을 받았습니다 : Powershell script for checking AD replication 내 스크립트의 논리를 해결하는 데 도움이되었습니다. 이후 추가 정보와 수표를 스크립트에 추가했으며 최종 결과는 다음과 같습니다.Powershell 스크립트가 로컬 컴퓨터에서 실행되지 않을 때 잘못된 결과를 출력합니다.

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

서버에서 권한을 부여 할 수 있습니까? 어떤 사용자 컨텍스트가 실패 할 때 실행중인 스크립트입니까? – Bassie

+0

실행 정책을 언급하고 있는지 확실하지 않지만 dataloop의 KB 기사에 따르면 powershell.exe -executionpolicy bypass-file을 사용하여 스크립트를 실행해야하는 powershell 플러그인에 대해 제안합니다. 또한 차이점을 보이지 않는 -noprofile 및 -noninteractive 스위치를 추가하려고 시도했습니다. 서버 중 하나의 현재 실행 정책은 제한되지 않도록 설정됩니다. –

+0

어쩌면 오류 세부 정보가 로그에 기록되는지 게시 할 수 있습니다. 유용한 단서를 제공 할 수 있습니다. – Bassie

답변

0

관심있는 사람들을 위해 dataloop-agent 서비스는 설치 중에 작성된 내장 dataloop-agent 사용자로 실행되며 관리자 권한이 없습니다.

해결 방법은 서비스가 로컬 시스템 사용자로 실행되도록 변경하는 것이 었습니다. GUI를 통해 수동으로 수행하거나 배치 스크립트로 자동화 할 수 있습니다.