问题
I'm trying to run a command to gather use profiles with certain requirements, here's my code:
#$numberOfDays = 30
#$numberOfDays
$profileStructsToRemove = Get-CimInstance Win32_UserProfile |
Where-Object {$_.LastUseTime -lt $(Get-Date).Date.AddDays(-$numberOfDays) } |
Where-Object {$_.LocalPath.ToUpper() -ne 'C:\USERS\ADMINISTRATOR'} |
Where-Object {$_.LocalPath.ToUpper() -ne 'C:\USERS\SOME_PROFILE_TO_KEEP'} |
Where-Object {$_.LocalPath.ToUpper() -ne 'C:\USERS\PUBLIC'}
$profileStructsToRemove #print
I use the $numberOfDays variable to determine the number of days subtracted from today's date that I want to use as the filter. Right now it's commented out, and the command succeeds, although since $numberOfDays isn't defined I assume it's using a null value? I'm not really sure but it works that way...
However, when I assign $numberOfDays to 30, it fails to populate the variable $profileStructsToRemove with ANYTHING at all. It just utterly fails. I could really use some input on why this is happenening.
- How is the command working when
$numberOfDaysisn't defined? Is it just a null value, or treating it as 0 for theAddDaysfunction? - Why is this command failing once
$numberOfDaysis assigned a value?
回答1:
Yes, it's null, which added zero days. This is fine - you can test with:
$(Get-Date).Date.AddDays($null)Are you sure there are profiles that match that data? Check the data when
$numberOfDaysisnullto confirm.
回答2:
gms0ulman's helpful answer answers question #1 well (converting $null to an [int] yields 0).
As for question #2:
At least on Windows 10 on a non-domain machine, the .LastUseTime property seemingly always returns the current date and time, which (a) makes it useless and (b) explains why you didn't see any results.
You could try to check the .LastDownloadTime instead, if that field has a value in your case - I presume it would only have a value if the profiles are roaming profiles.
For reference, here's the full list of available time stamps:LastAttemptedProfileDownloadTime, LastAttemptedProfileUploadTime, LastBackgroundRegistryUploadTime, LastDownloadTime, LastUploadTime, LastUseTime.
As for how to optimize the code in your question in general:
PowerShell string operators are case-insensitive by default, so there's no need for
.toUpper().You could combine your multiple
Where-Objectcalls into a single one, and you can use-notinwith an array of paths on the RHS, instead of using-newith individual paths.
To put it all together (PSv3+; keeping in mind that comparing against .LastUsedTime may be pointless):
$profileStructsToRemove = Get-CimInstance win32_userprofile | Where-Object {
$_.LastUseTime -lt $(Get-Date).Date.AddDays(-$numberOfDays) -and
$_.LocalPath -notin 'C:\USERS\ADMINISTRATOR',
'C:\USERS\SOME_PROFILE_TO_KEEP',
'C:\USERS\PUBLIC'
}
来源:https://stackoverflow.com/questions/52632465/powershell-command-fails-after-variable-is-used