2017-04-10 13 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を使用して手動で実行することも、バッチスクリプトで自動化することもできます。

関連する問題