I'm attempting to create a script that cleans up temporary profiles on a 2008-R2 server.
Weird thing is I'm positive I had this working fine before our holiday, now the script doesn't work after said holiday :(.
The script:
$keys = ls "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*.bak"
foreach ($key in $keys){
$sid = $key.name | select-string -Pattern 'S-\d-\d+-(\d+-){1,14}\d+' | out-string
$sid = ($sid).Split('\')[6]
$sid = ($sid).Split('.')[0]
$profile = get-wmiobject win32_userprofile -computername localhost | where-object {$_.SID -eq $sid}
$profile.Delete()
}
If I run that, or any form of modification of that delete method, I get:
Exception calling "Delete" with "0" argument(s): ""
At C:\temp\remove_temp_profiles.ps1:7 char:18
($profile).Delete <<<< ()
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : DotNetMethodException
If I run a:
get-wmiobject win32_userprofile | get-member
I can see that the delete method is not there. It's supposedly "hidden" whatever that means.
Apart from the delete not working, the rest of the script works perfectly (regex is another battle haha!)
I've also instead attempted to use remove-wmiobject instead. However it causes errors with:
Remove-WmiObject :
At C:\temp\remove_temp_profiles.ps1:7 char:28
+ $profile | remove-wmiobject <<<<
+ CategoryInfo : InvalidOperation: (:) [Remove-WmiObject], COMException
+ FullyQualifiedErrorId : RemoveWMICOMException,Microsoft.PowerShell.Commands.RemoveWmiObject
I've spent ages and ages googling and trying different things, and all of the solutions appear to be "use the $variable.Delete() and it works fine". I don't know how to program (only basic scripting) so apologies for my newness.
This could be because the profile is still considered to be loaded. You can verify this by looking at the loaded property. You should also look at using the -Filter parameter instead of piping everything to Where-Object.
$keys = ls "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*.bak"
foreach ($key in $keys){
$sid = $key.name | select-string -Pattern 'S-\d-\d+-(\d+-){1,14}\d+' | out-string
$sid = ($sid).Split('\')[6]
$sid = ($sid).Split('.')[0]
$profile = get-wmiobject win32_userprofile -computername localhost -Filter "SID -eq '$sid' AND NOT Loaded='True'"
$profile.Delete()
}
If you just want to see if profiles are still loaded:
Get-WMIObject win32_userprofile -computername localhost -Filter "Loaded='True'" |
Select SID,LocalPath,Loaded
Related
New to PowerShell, attempting to cobble scripts together to:
Pull a list of Servers in Active Directory (done).
Query each server for a list of SERVICE accounts running under ADMINISTATOR credentials.
Can anyone guide me...prefer to export out to a CSV file, etc.
THANK YOU!
THIS IS WHAT I HAVE:
Import-Module ActiveDirectory
$Serverlist = Get-ADComputer -Filter 'operatingsystem -like "*server*" -and enabled -eq "true"' `
-Properties Name
Sort-Object -Property Name |
foreach ($Server in $Serverlist) {
$Server
Get-WmiObject Win32-Service | Select DisplayName, StartName | Where-Object {$_.StartName -eq "administrator"}
GETTING THESE ERRORS:
At line:5 char:18
+ foreach ($Server in $Serverlist) {
+ ~~
Unexpected token 'in' in expression or statement.
At line:5 char:17
+ foreach ($Server in $Serverlist) {
+ ~
Missing closing ')' in expression.
At line:5 char:32
+ foreach ($Server in $Serverlist) {
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
Assuming you have permissions to remotely query those hosts you can try the following:
$computers = (Get-ADComputer -Filter 'operatingsystem -like "*server*" -and enabled -eq "true"').DNSHostName
Get-CimInstance Win32_Service -Filter "StartName LIKE '%Administrator%'" -ComputerName $computers
| Select-Object DisplayName, StartName, PSComputerName
Notes
Get-CimInstance and Get-WmiObject (replaced in this example, since its no longer maintained in new PowerShell versions) can invoke queries in parallel, hence no loop is required.
Both cmdlets allow queries with WQL. Faster filtering this way than with powershell.
Only real reason to use Get-WmiObject instead of Get-CimInstance could be if using DCOM as your remoting protocol. At which point you could use New-CimSessionOption -Protocol DCOM and connect using a CimSession. Functionality for both cmdlets is mostly the same.
You should include PSComputerName in your Select-Object statement to understand from which computer the object is coming from.
I have this piece of code , developed in PowerShell 4.0
$myArray=#()
$hT=#{}
$hTAux=#{}
#(Get-CimInstance -ClassName Win32_Process -Filter "Name = 'firefox.exe'" |Select-Object #{Name='TotalProcessorTime';Expression={(Get-Process -Id $_.ProcessId).TotalProcessorTime}},Name,ProcessId,CommandLine |Where-Object { $_.TotalProcessorTime -ne $null }).ForEach({
$o= new-object psobject -Property #{"ProcessId"=$_.ProcessId;"Name"=$_.Name;"TotalProcessorTime"=Expression={(Get-Process -Id $_.ProcessId).TotalProcessorTime};"CommandLine"=$_.CommandLine}
$myArray.Add($hT.Add($o.ProcessId,$o))
})
The aim is to store, the values in array of hastables.
But, when trying to retrieve the info again to work with it, I dont know how I could access properly to the value stored in the hashtable
The piece of code below doesnt work:
$var=2
$c=(Get-CimInstance -ClassName Win32_Process -Filter "Name = 'firefox.exe'" |Select-Object ProcessId,Name,#{Name='TotalProcessorTime';Expression={(Get-Process -Id $_.ProcessId).TotalProcessorTime}},CommandLine |Where-Object { $_.TotalProcessorTime -ne $null }).Length
while($var -ne $c){
$hTAux=$myArray.GetValue($var)
$hTAux.GetEnumerator() | % {$_.key} | Stop-Process
$var++
}
Shows me the error:
Exception when calling to "GetValue" with the arguments "1": IndexOutOfRangeException
$hTAux=$myArray.GetValue($var)
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IndexOutOfRangeException
Anyhelp to solve this issue would be appreciated
Many thanks
Regards
I'm doing the following powershell line, and for some reason it's finding a syntax error with it, but I'm not sure why, and I can't find it in an internet search:
$eventInitTerminate = Get-WinEvent -FilterHashtable #{LogName='Application';ProviderName='chromoting';StartTime=$initTime;EndTime=$crashOccurredTime;} -ErrorAction SilentlyContinue | Where-Object -PipelineVariable Message -Match 'Channel'
I can see Channel in my chromoting ProviderName for Application event-log, but for some reason it's not working here and I get the error message:
Where-Object : The specified operator requires both the -Property and -Value parameters. Provide values for both parameters, and then try the
command again.
At E:\dirName\CrashAfterExclude_test2.ps1:25 char:192
+ ... tlyContinue | Where-Object -PipelineVariable Message -Match 'Channel'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Where-Object], PSArgumentException
+ FullyQualifiedErrorId : ValueNotSpecifiedForWhereObject,Microsoft.PowerShell.Commands.WhereObjectCommand
I am trying to delete user profiles in Powershell.
Till Yesterday all Remove-WmiObject were working properly.
But today they are not working.
Please check the command below:
Get-WMIObject -class Win32_UserProfile | Where {
((!$_.Special) -and
($_.LocalPath -ne "C:\Users\Administrator") -and
($_.LocalPath -ne "C:\Users\UpdatusUser") -and
($_.LocalPath -eq "C:\Users\$user"))
} | Remove-WmiObject
I am getting the error below:
+ CategoryInfo : NotSpecified: (:) [Remove-WmiObject], FileLoadException
+ FullyQualifiedErrorId : System.IO.FileLoadException,Microsoft.PowerShell.Commands.RemoveWmiObject
I have also tried $profile.Delete() method. This isn't working either. I get method not found error.
I have also checked whether the profile is loaded or not.
I have also tried logging users off before deleting their profile.
I have also tried using Remove-Cmiinstance, but same result.
I am trying to get the OWNER of a process, code :
(Get-WmiObject -class win32_process | where{$_.ProcessName -eq 'explorer.exe'}).getowner() | Foreach-Object user | out-string**
This works great under win8 but in win7 I get this msg :
ForEach-Object : Cannot bind parameter 'Process'. Cannot convert the "user" val
ue of type "System.String" to type "System.Management.Automation.ScriptBlock".
At C:\Program Files (x86)\Advanced Monitoring Agent GP\scripts\9660.ps1:1 char:
108
+ (Get-WmiObject -class win32_process | where{$_.ProcessName -eq 'explorer.exe'
}).getowner() | Foreach-Object <<<< user | out-string
+ CategoryInfo : InvalidArgument: (:) [ForEach-Object], Parameter
BindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerSh
ell.Commands.ForEachObjectCommand
Help please! Thank you for the time.
Instead of foreach-object user, use select -expand user. This is equivalent to doing foreach-object { $_.user } which is probably what you meant to do. Improvements to flexibility in the grammar allow your first attempt in later versions of powershell.
The older version of Powershell won't work with the simplified syntax. This should work on either one:
(Get-WmiObject -class win32_process |
where{$_.ProcessName -eq 'explorer.exe'}).getowner() |
Foreach-Object { $_.user | out-string }
(Get-WmiObject -class win32_process | where{$_.ProcessName -eq 'explorer.exe'}).getowner() | select user
I had a similar problem but in my case, there was a non-printable character in my script that appeared after one of the }'s. ASCII code 03. I found that by opening the script in a binary editor (Textpad8). I deleted this character and it fixed the problem for me.