2017-07-12 8 views
0

同じサーバーセッションを複数回実行しているForEach-Objectプロパティに問題があります。ただし、リスト上のサーバーセッションは一度だけ実行されます。これはループの問題だと私は思う。私はExport-Csvから-Appendを削除した場合ForEach-Objectループの問題

if (Test-Path 'H:\demo\session\run11.csv') { 
    Clear-Content 'H:\demo\session\run11.csv' 
} 

$Servers = Get-Content 'H:\demo\computernames.txt' 
$openservers = @() 

foreach ($Server in $Servers) { 
    if (-not (Test-Connection $Server -Count 1 -Quiet)) { continue } 

    if (-not (Convert-QueryToObjects $Server -ErrorAction SilentlyContinue)) { 
     $openservers += $server 
     $openservers | Out-File 'H:\demo\session\openservers.txt' 
    } else { 
     Convert-QueryToObjects -Name $Server | Where-Object { 
      @('Disconnected','Active') -contains $_.SessionState 
     } | Export-Csv H:\demo\session\run11.csv -NoTypeInformation -Append 
    } 
} 

function Disconnect-LoggedOnUser { 
    Param(
     [Parameter(
      Mandatory, 
      ValueFromPipeline, 
      ValueFromPipelineByPropertyName, 
      Position=0 
     )] 
     [string[]]$ComputerName, 
     [Parameter(
      Mandatory, 
      ValueFromPipelineByPropertyName 
     )] 
     [int[]]$Id 
    ) 

    Begin { 
     $OldEAP = $ErrorActionPreference 
     $ErrorActionPreference = 'Stop' 
    } 

    Process { 
     foreach ($Computer in $ComputerName) { 
      $Id | ForEach-Object { 
       Write-Verbose "Attempting to disconnect session $Id on $Computer" 
       try { 
        rwinsta $_ /server:$Computer 
        Write-Verbose "Session $Id on $Computer successfully disconnected" 
       } catch { 
        Write-Verbose 'Error disconnecting session displaying message' 
        Write-Warning "Error on $Computer, $($_.Exception.Message)" 
       } 
      } 
     } 
    } 

    End { 
     $ErrorActionPreference = $OldEAP 
    } 
} 

Import-Csv 'H:\demo\session\run11.csv' | Where-Object { 
    ($_.SessionState -eq 'Disconnected') -or 
    (($_.IdleTime -like "*:*") -and ($_.IdleTime -gt "00:59")) 
} | ForEach-Object { 
    Disconnect-LoggedOnUser -ComputerName $_.ComputerName -Id $_.ID -Verbose 
} 

私はもはやループの問題を持っていません。ただし、すべてのオブジェクトがCSVにエクスポートされるわけではありません(リストの最後のサーバだけがエクスポートされます)。すべてのサーバーをCSVにエクスポートするには、どのようにして、指定した各セッションを1回だけ実行する必要がありますか?私はここに私のGitHubの要旨にhere

を(二つの機能を含め、私のコードの残りの部分を掲載

は、私が取得していますサンプル出力です:

 
VERBOSE: Attempting to disconnect session 24 on XXX 
VERBOSE: Error disconnecting session displaying message 
WARNING: Error on XX, Could not reset session ID 24, Error code 5 

VERBOSE: Attempting to disconnect session 24 on XXX 
VERBOSE: Error disconnecting session displaying message 
WARNING: Error on XX, Could not reset session ID 24, Error code 5 

VERBOSE: Attempting to disconnect session 3 on XX 
VERBOSE: Error disconnecting session displaying message 
WARNING: Error on XX, Could not reset session ID 3, Error code 5 

VERBOSE: Attempting to disconnect session 24 on XXX 
VERBOSE: Error disconnecting session displaying message 
WARNING: Error on XX, Could not reset session ID 24, Error code 5 

VERBOSE: Attempting to disconnect session 3 on XX 
VERBOSE: Error disconnecting session displaying message 
WARNING: Error on XX, Could not reset session ID 3, Error code 5 


VERBOSE: Attempting to disconnect session 14 on XX 
VERBOSE: Error disconnecting session displaying message 
WARNING: Error on XX, Could not reset session ID 14, Error code 5 
+0

不適切にバランスの良い中括弧のように見えます。 'Where-Object'フィルタスクリプトブロック内の' Select-Object' *にパイプします。 'Select-Object'の直前まで' Export-Csv'の前の最後の '}'を移動してください –

+0

'Where-Object'(' Where-Object {{..} ')の 'Where-Object'条件ブロックの中括弧。} | Select-Object {...}} ')? –

+0

@ MathiasR.Jessenしかし、それをさらに楽しみながら遊んだ後、私は実際にはそれらの値がスクリプトの前半で定義されているので(ここでは示されていない) 。しかし、私はまだ問題を抱えています。更新された質問をご覧ください。 – russell

答えて

0

はあなたの最初に関数定義を移動します

のようなものに

foreach ($Server in $Servers) { 
    if (-not (Test-Connection $Server -Count 1 -Quiet)) { continue } 

    if (-not (Convert-QueryToObjects $Server -ErrorAction SilentlyContinue)) { 
     $openservers += $server 
     $openservers | Out-File 'H:\demo\session\openservers.txt' 
    } else { 
     Convert-QueryToObjects -Name $Server | Where-Object { 
      @('Disconnected','Active') -contains $_.SessionState 
     } | Export-Csv H:\demo\session\run11.csv -NoTypeInformation -Append 
    } 
} 

Import-Csv 'H:\demo\session\run11.csv' | Where-Object { 
    ($_.SessionState -eq 'Disconnected') -or 
    (($_.IdleTime -like "*:*") -and ($_.IdleTime -gt "00:59")) 
} | ForEach-Object { 
    Disconnect-LoggedOnUser -ComputerName $_.ComputerName -Id $_.ID -Verbose 
} 

をコードと変更0

$culture = [Globalization.CultureInfo]::InvariantCulture 
$reftime = [DateTime]::ParseExact('00:59', 'hh:mm', $culture) 

$Servers | Where-Object { 
    Test-Connection $Server -Count 1 -Quiet 
} | ForEach-Object { 
    Convert-QueryToObjects $_ -ErrorAction SilentlyContinue 
    if (-not $?) { $openservers += $_ } 
} | Where-Object { 
    $_.SessionState -eq 'Disconnected' -or 
    ($_.SessionState -eq 'Active' -and 
    [DateTime]::ParseExact($_.IdleTime, 'hh:mm', $culture) -gt $reftime) 
} | ForEach-Object { 
    Disconnect-LoggedOnUser -ComputerName $_.ComputerName -Id $_.ID -Verbose 
} 

$openservers | Out-File 'H:\demo\session\openservers.txt' 
+0

この問題をお手伝いいただきありがとうございます – russell