I am currently trying to run a script that is as follows (to find and uninstall CCleaner):
Get-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object {$_.DisplayName -eq "CCleaner"} -OutVariable Results **{
& "$($Results.InstallLocation)\uninst.exe"
}
The error is:
Where-Object : A positional parameter cannot be found that accepts argument
& "$($Results.InstallLocation)\uninst.exe" /S
.At line:1 char:98
+ Get-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object <<<< {$_.DisplayName -eq "CCleaner"} -OutVariable Results {
+ CategoryInfo : InvalidArgument: (:) [Where-Object], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.WhereObjectCommand
The last part there seems to be a problem. I am sure this is because I am writing this in PS v3 but I'm running this as a PSSession on PC's running PS v2 or v1.
I think this is what you're after:
Get-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object {$_.DisplayName -eq "CCleaner"} | ForEach-Object { & "$($_.InstallLocation)\uninst.exe" }
Otherwise, you need to use a named parameter after "Results"
Related
This Code will work:
Get-NetAdapter | Where-Object {$_.InterfaceDescription -match 'Ethernet' -or $_.InterfaceDescription -match 'Wireless'}
I want start it from Taskscheduler (cmd) or in powershell
This code will not work:
Powershell.exe -Command "Get-NetAdapter | Where-Object {$_.InterfaceDescription -match 'Ethernet' -or $_.InterfaceDescription -match 'Wireless'}"
Error:
... etAdapter | Where-Object {.InterfaceDescription -match 'Ethernet'-or ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : ObjectNotFound: (.InterfaceDescription:String) [Where-Object], CommandNotFoundException
FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.WhereObjectCommand
Also as an base64 string same error.
Have anyone an idea why it will not work as an command but direct as command in ps?
Powershell.exe -Command "Get-NetAdapter ; Where-Object {$_.InterfaceDescription -match 'Ethernet' -or $_.InterfaceDescription -match 'Wireless'}"
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'm trying to understand the .uninstall() method.
From this link it looks like the method .uninstall() only works when used with Get-WmiObject -Class Win32_Product. But this means it will consider 32-bit software only and not 64-bit software.
So I wrote this few lines in order to uninstall Erlang, which is 64-bit:
# Check if a Software ins installed
function Check_Program_Installed($programName) {
$x86_check = ((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") |
Get-ItemProperty |
Where-Object {$_.DisplayName -like "*$programName*" } |
Select-Object -Property DisplayName, UninstallString) |
Format-Table
if (Test-Path 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall') {
$x64_check = ((Get-ChildItem "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall") | Get-ItemProperty | Where-Object {$_.DisplayName -like "*$programName*" } | Select-Object -Property DisplayName, UninstallString) | Format-Table
}
if ($x86_check -and $x64_check -eq $null) {
Write-Host "$programName is not installed on this computer" -ForegroundColor Green
#continue
} elseif ($x86_check -or $x64_check -ne $null) {
Write-Host "On this computer is installed " -ForegroundColor Red
$x86_check
$x64_check
$x86_check.uninstall()
$x64_check.uninstall()
}
}
# Erlang check
Write-Host "Checking if Erlang exist " -NoNewline
Check_Program_Installed("Erlang")
Write-Host "The End: the script ends here" -ForegroundColor Yellow
but unfortunately it returns me the error:
You cannot call a method on a null-valued expression. At
C:\Users\Admin\Desktop\test.ps1:17 char:3
+ $x86_check.uninstall()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Method invocation failed because
[Microsoft.PowerShell.Commands.Internal. Format.FormatStartData] does
not contain a method named 'Uninstall'. At
C:\Users\Admin\Desktop\test.ps1:18 char:3
+ $x64_check.uninstall()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
I believe the root cause it that there are DisplayName and UninstallString in the variable, right?
A way out I found is to use:
'"C:\Program Files\erl8.3\Uninstall.exe'" | cmd
in order to uninstall but this is not using the .uninstall() method which is what I want to use.
Is Microsoft saying that you can use .uninstall() only with 32-bit architecture and for 64-bit you need to find your own way out?
If so it's quite rudimentary
The reply is NO.
.uninstall() can only be used with Get-WmiObject -Class Win32_Product and therefore will only uninstall 32-bit programs.
Source 1
Source 2
Source 3
Source 4
Source 5
There might be an alternative way out uninstall both 32-bit and 64-bit program with:
Get-Package "*Erlang*"
At least finds the program but
Get-Package "*Erlang*" | Uninstall-Package -Force
won't uninstall
Can explain why philosophically this doesn't work?
Just as a learning example, I wanted to see the properties of the get-service cmdlet, without the events or methods.
PS C:\Users\Neal> get-service | get-member | {$_.name -eq "Property"}
Result:
At line:1 char:29
+ get-service | get-member | {$_.name -eq "Property"}
+ ~~~~~~~~~~~~~~~~~~~~~~~~
Expressions are only allowed as the first element of a pipeline.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ExpressionsMustBeFirstInPipeline
{$_.name -eq "Property"} is just a scriptblock. If you want to use Where-Object to filter the results of get-member, you need to type Where-Object:
PS C:\Users\Neal> get-service | get-member | Where-Object {$_.name -eq "Property"}
or you can use where, which is an alias for Where-Object:
PS C:\Users\Neal> get-service | get-member | where {$_.name -eq "Property"}
There is even a special character ? which refers to Where-Object:
PS C:\Users\Neal> get-service | get-member | ? {$_.name -eq "Property"}
All three examples given above do the same thing. Choosing between them is simply a matter of style.
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