问题
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
$numberOfDays
isn't defined? Is it just a null value, or treating it as 0 for theAddDays
function? - Why is this command failing once
$numberOfDays
is 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
$numberOfDays
isnull
to 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-Object
calls into a single one, and you can use-notin
with an array of paths on the RHS, instead of using-ne
with 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