获取最后一个没有AD的用户登录时间

时间:2016-08-23 16:11:38

标签: powershell

我正在尝试创建一个脚本,该脚本可以在30天内获取未在特定计算机上登录的用户配置文件,但不使用活动目录,但我的脚本无法正常工作。我使用的是Powershell版本3.这是我的代码:

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
}

我尝试将-ge更改为行$objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30}中的-le,以及更改后的范围,但无论我的更改如何,它仍然会给我相同的计算机列表。

1 个答案:

答案 0 :(得分:0)

脚本存在一些问题,最值得注意的是你使用Where-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