简体   繁体   English

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

[英]get last user logon time without AD

I'm trying to create a script that can get the user profiles that haven't logged on a specific computer within 30 days NOT using active directory but my script didn't work. 我正在尝试创建一个脚本,可以在30天内获取未在特定计算机上登录的用户配置文件,但不使用活动目录,但我的脚本无效。 I am using Powershell version 3. This is my code: 我使用的是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
}

I tried to change the -ge to -le in the line $objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30} 我试图在$objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30}更改-ge到-le。 $objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30} , as well as changing the range after it but it still gave me the same list of computers regardless of my changes. $objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30} ,以及更改后的范围,但它仍然给了我相同的计算机列表,无论我的更改如何。

There are a few problems with the script, most notable is that your use of Where-Object is testing an object (SID) that doesn't know anything about dates. 这个脚本有一些问题,最值得注意的是你使用Where-Object正在测试一个对日期一无所知的对象(SID)。

I would break it down a little differently. 我会稍微区别一点。 I would write a function to catch all the stuff I need to do to attempt to figure out the last logon. 我会编写一个函数来捕获我需要做的所有事情,以试图找出最后一次登录。 That's my goes in my stack of utility functions in case I need it again. 这是我的实用功能堆栈,以防我再次需要它。

Then I have something to use that function which deals with implementing the logic for the immediate requirement. 然后我有一些东西要使用该功能来处理为即时需求实现逻辑。

So you end up with this. 所以你最终得到了这个。 It's a bit long, see what you think. 这有点长,看看你的想法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM