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. I am using Powershell version 3. This is my code:
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}
, as well as changing the range after it but it still gave me the same list of computers regardless of my changes.
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.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.