2016-08-23 2 views
1

アクティブなディレクトリを使用せずに30日以内に特定のコンピュータにログオンしていないユーザープロファイルを取得できるスクリプトを作成しようとしましたが、スクリプトが機能しませんでした。私はこれが私のコードでPowerShellのバージョン3を使用しています:ADなしの最後のユーザーログオン時間を取得

netsh advfirewall firewall set rule group="Windows Management Instrumentation (WMI)" new enable=yes 
$ComputerList = Get-Content C:\temp\Computers1.txt 
$myDomain = Get-Content C:\temp\Domain.txt 
$csvFile = 'C:\temp\Profiles.csv' 

# Create new .csv output file 
New-Item $csvFile -type file -force 

# Output the field header-line to the CSV file 
"HOST,PROFILE" | Add-Content $csvFile 

# Loop over the list of computers from the input file 
foreach ($Computer in $ComputerList) { 

    # see if ping test succeeds for this computer 
    if (Test-Connection $Computer -Count 3 -ErrorAction SilentlyContinue) { 

     $ComputerFQDN = $Computer + $myDomain 
     $Profiles = Get-WmiObject -Class Win32_UserProfile -Computer $ComputerFQDN | Where{$_.LocalPath -notlike "*$env:SystemRoot*"} 

     foreach ($profile in $profiles) { 
     try { 
       $objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30} 

       #| Where-Object {$_.LastLogonDate -le $CurrentDate.AddDays(-60)} 
       $objuser = $objsid.Translate([System.Security.Principal.NTAccount]) 
       $objusername = $objuser.value 
      } catch { 
       $objusername = $profile.LocalPath 
      } 
      switch($profile.status){ 
       1 { $profileType="Temporary" } 
       2 { $profileType="Roaming" } 
       4 { $profileType="Mandatory" } 
       8 { $profileType="Corrupted" } 
       default { $profileType = "LOCAL" } 
      } 
      $User = $objUser.Value 

      #output profile detail for this host 
      "$($Computer.toUpper()), $($objusername)" | Add-Content $csvFile 
     } 

    } else { 

      #output failure message for this host 
      "$($Computer.toUpper()), PING TEST FAILED" | Add-Content $csvFile 
    } 

#LOOP 
} 

を私はライン$objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30}に-leする-geを変更しようとしただけでなく、それの後に範囲を変更するが、それはまだ私に同じリストを与えました私の変更にかかわらずコンピュータの

答えて

0

スクリプトでいくつかの問題がありますが、最も注目すべきはどこ-Objectのご使用は日付については何も知らないオブジェクト(SID)をテストしているということです。

私は少し違ってそれを分解するでしょう。私は、最後のログオンを調べるために必要なすべての要素をキャッチする関数を作成します。それは私がもう一度それを必要とする場合のために私のユーティリティ機能のスタックで私の行くことです。

次に、すぐに必要なロジックを実装するための機能を使用します。

これで終わります。ちょっと長いです、あなたの考えを見てください。

function Get-LastLogon { 
    [CmdletBinding()] 
    param(
     [Parameter(ValueFromPipeline = $true)] 
     [String]$ComputerName = $env:COMPUTERNAME 
    ) 

    process { 
     Get-WmiObject Win32_UserProfile -ComputerName $ComputerName -Filter "Special='FALSE'" | ForEach-Object {  
      # Attempt to get the UserAccount using WMI 
      $userAccount = Get-WmiObject Win32_UserAccount -Filter "SID='$($_.SID)'" -ComputerName $ComputerName 

      # To satisfy WMI all single \ in a path must be escaped. 
      # Prefer to use NTUser.dat for last modification 
      $path = (Join-Path $_.LocalPath 'ntuser.dat') -replace '\\', '\\' 
      $cimObject = Get-WmiObject CIM_DataFile -Filter "Name='$path'" -ComputerName $ComputerName 
      if ($null -eq $cimObject) { 
       # Fall back to the directory 
       $path = $_.LocalPath -replace '\\', '\\' 
       $cimObject = Get-WmiObject CIM_Directory -Filter "Name='$path'" -ComputerName $ComputerName 
      } 
      $lastModified = $null 
      if ($null -ne $cimObject) { 
       $lastModified = [System.Management.ManagementDateTimeConverter]::ToDateTime($cimObject.LastModified) 
      } 
      # See if LastUseTime is more useful. 
      $lastUsed = $null 
      if ($null -ne $_.LastUseTime) { 
       $lastUsed = [System.Management.ManagementDateTimeConverter]::ToDateTime($_.LastUseTime) 
      } 

      # Profile type 
      $profileType = switch ($_.Status) { 
       1 { "Temporary" } 
       2 { "Roaming" } 
       4 { "Mandatory" } 
       8 { "Corrupted" } 
       0 { "LOCAL" } 
      } 

      [PSCustomObject]@{ 
       ComputerName = $ComputerName 
       Username  = $userAccount.Caption 
       LastChanged = $lastModified 
       LastUsed  = $lastUsed 
       SID   = $_.SID 
       Path   = $_.LocalPath 
       ProfileType = $profileType 
      } 
     } 
    } 
} 

$myDomain = Get-Content C:\temp\Domain.txt 
Get-Content C:\temp\Computers1.txt | ForEach-Object { 
    $ComputerName = $_ + $myDomain 
    if (Test-Connection $ComputerName -Quiet -Count 3) { 
     Get-LastLogon -ComputerName $ComputerName | Select-Object *, @{Name='Status';Expression={ 'OK' }} | 
      Where-Object { $_.LastChanged -lt (Get-Date).AddDays(-30) } 
    } else { 
     # Normalise the output so we don't lose columns in the export 
     $ComputerName | Select-Object @{Name='ComputerName';e={ $ComputerName }}, 
      Username, LastChanged, LastUsed, SID, Path, ProfileType, @{Name='Status';Expression={ 'PING FAILED' }} 
    } 
} | Export-Csv 'C:\temp\Profiles.csv' -NoTypeInformation 
+0

私はあなたのコードを試してみましたが、このエラーを得た:LastChanged:この用語は、「LastChanged」は、コマンドレット、関数、スクリプトファイル、または操作可能なプログラムの名前として認識されません。名前のスペルを確認するか、パスが含まれている場合は、パスが正しいことを確認してから、もう一度やり直してください。 Cで :\ユーザー\テスト\のSOF.ps1:59文字:28 + 場合、オブジェクト{LastChanged -lt(GET-日).AddDays(-30)} + ~~~~~~~~~~ 〜 + CategoryInfo:ObjectNotFound:(LastChanged:文字列)[]、CommandNotFoundException + FullyQualifiedErrorId:CommandNotFoundException使用しているのPowerShellのバージョン –

+0

?あなたは私のバージョン(5)に対して簡単なテストを行っただけなので、言わなかった。 –

+0

私は質問を更新しました。私はバージョン3を使用しています –

関連する問題