PS | Deleting Local User Profile | Get-WmiObject -Query Not working - powershell

I am literally 1 Line away from getting this PS Task completed. Would one of you mind taking a look? This script simply checks the users directory, checks each local users creation date, and deletes it using WMIObject. Everything works up to line 34 (Marked it with ===> in Code block). Error being thrown on my WMI Query. I cannot find out why... Working with WMIExplorer it looks correct.
$Admin = "Administrator"
foreach($file in Get-ChildItem C:\Users\)
{
if ($file -in $Admin)
{
Write-Host = "`r`nUser account is" $file ". This is an Administrator Account, it will not be deleted."
}
else
{
Write-Host = "`r`nUser account is" $file ". Checking profiles age..."
$FileDate = (Get-item C:\Users\$file).CreationTime
Write-Host = $FileDate
$TestDate = (Get-Date).addDays(-30)
Write-Host = $TestDate
If ($FileDate -lt $TestDate)
{
Write-Host = "Since" $file "is older than 30 Days (" $FileDate ") it will be deleted."
$UserAccountPath = "C:\Users\$file"
====> $WMIQuery = "SELECT * FROM Win32_UserProfile WHERE localpath = $UserAccountPath"
$UserProfile = Get-WmiObject -Query $WMIQuery -ComputerName $Computer
Remove-WmiObject -InputObject $UserProfile
}
else
{
Write-Host = "Since File is dated less than 30 days old (" $FileDate ") it will not need to be deleted."
}
}
}
When it is run I get the following Error:
Get-WmiObject : Invalid query "SELECT * FROM Win32_UserProfile WHERE localpath = C:\Users\radconrm"
At C:\Users\AVC00\Documents\PowerShell\Profile Maintenance\TestCommands.ps1:18 char:13
+ $profile = (Get-WmiObject -Query $WMIQuery -ComputerName $Computer)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Remove-WmiObject : Cannot bind argument to parameter 'InputObject' because it is null.
At C:\Users\AVC00\Documents\PowerShell\Profile Maintenance\TestCommands.ps1:19 char:31
+ Remove-WmiObject -InputObject $profile
+ ~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-WmiObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveWmiObject
I look forward to your insight! Thank you for your time in advanced!

Double the backslashes. Add quotes to what localpath is equal to. It's like SQL.
$UserAccountPath = "C:\\Users\\$file"
$WMIQuery = "SELECT * FROM Win32_UserProfile WHERE localpath = '$UserAccountPath'"
$UserProfile = Get-WmiObject -Query $WMIQuery -ComputerName $Computer
You may find something like this easier:
get-wmiobject win32_userprofile | where localpath -eq c:\users\$file

Related

Getting Registry Key of all machines in the domain

sorry if it's a silly question. I'm trying to get the "EnableDCOM" Registry Key of all the machines on the domain and disable them. I'm kinda stuck with getting the status of the registry key.
Get-Adcomputer -Filter * | Get-itemProperty -path HKLM:\Software\Microsoft\OLE -name "EnableDCOM"
Here is the error:
Get-ItemProperty : Cannot process argument transformation on parameter 'Credential'. userName
At line:1 char:28
... -filter * | Get-ItemProperty -path HKLM:\Software\Microsoft\OLE -name ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidData: (CN=DAYGROUP-PCI...=daygroup,DC=ca:PSObject) [Get-ItemProperty], ParameterB
indingArgumentTransformationException
FullyQualifiedErrorId : ParameterArgumentTransformationError,Microsoft.PowerShell.Commands.GetItemPropertyComman
d
After trying to use the domain admin credential:
The provider does not support the use of credentials. Perform the operation again without specifying credentials.
At line:1 char:1
get-adcomputer -filter * | Get-ItemProperty -path HKLM:\Software\Micr ...
+ CategoryInfo : NotImplemented: (:) [], PSNotSupportedException
+ FullyQualifiedErrorId : NotSupported
This code can help you. Don`t forget to specify different credential if needed.
$ADComputers = ( Get-ADComputer -Filter * ).Name
$ResultArray = #()
foreach ( $Computer in $ADComputers ){
#Maybe you need specify different credential -Credential $cred
$Value = Invoke-Command -ComputerName $Computer -ScriptBlock {
$Value = Get-ItemPropertyValue -path 'HKLM:\Software\Microsoft\OLE' -name 'EnableDCOM'
return $Value
}
$PSO = [PSCustomObject]#{
Computer = $Computer
Value = $Value
}
$ResultArray += $PSO
}
$ResultArray

I'm having issues with removing profiles in PowerShell

I have developed several scripts to remove unused profiles from machines with the exception of a few important accounts. Every script that I use always give me the same error when using the Remove-WmiObject, Remove-CimInstance, and .Delete(). I am certain that all of these scripts should work, but I receive the same error. Please see the below script and attached error. There is something wrong with my machine that is blocking me from using any of these functions. So my question: Is there anything I can do to get these functions to work for me or troubleshoot the issue? (I can attach other scripts and errors if needed)
Script:
$Admin = "Administrator","Public","Default","Administrator"
foreach($file in Get-ChildItem C:\Users\)
{
if ($file -in $Admin)
{
Write-Host = "`r`nUser account is" $file ". This is an Administrator Account, it will not be deleted."
}
else
{
Write-Host = "`r`nUser account is" $file ". Checking profiles age..."
$FileDate = (Get-item C:\Users\$file).CreationTime
Write-Host = $FileDate
$TestDate = (Get-Date).addDays(-30)
Write-Host = $TestDate
If ($FileDate -lt $TestDate)
{
Write-Host = "Since" $file "is older than 30 Days (" $FileDate ") it will be deleted."
$UserAccountPath = "C:\\Users\\$file"
$WMIQuery = "SELECT * FROM Win32_UserProfile WHERE localpath = '$UserAccountPath'"
$UserProfile = get-wmiobject win32_userprofile | Where-Object localpath -EQ $file.FullName
Remove-WmiObject -InputObject "$UserProfile"
}
else
{
Write-Host = "Since File is dated less than 30 days old (" $FileDate ") it will not need to be deleted."
}
}
}
Error:
Remove-WmiObject :
At line:28 char:17
+ Remove-WmiObject -InputObject "$UserProfile"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Remove-WmiObject], FileLoadException
+ FullyQualifiedErrorId : System.IO.FileLoadException,Microsoft.PowerShell.Commands.RemoveWmiObject
My past post might help for some background info: How to delete old profiles with script .
$sidToRemove = [System.Security.Principal.SecurityIdentifier]::new([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $null).ToString()
Get-WmiObject -Class Win32_UserProfile -Filter "SID = '$($sidToRemove)' AND SPECIAL = 'FALSE' AND LOADED = 'FALSE'" |
ForEach-Object { $_.Delete() }
And you can not remove public and default profiles as they are not profiles actually.

How to delete old profiles with script

So I am trying to adapt this code I got from another post for the needs of my current organization. Please see below code:
$Admin = "Administrator","Public","Default","Administrator"
foreach($file in Get-ChildItem C:\Users\)
{
if ($file -in $Admin)
{
Write-Host = "`r`nUser account is" $file ". This is an Administrator Account, it will not be deleted."
}
else
{
Write-Host = "`r`nUser account is" $file ". Checking profiles age..."
$FileDate = (Get-item C:\Users\$file).CreationTime
Write-Host = $FileDate
$TestDate = (Get-Date).addDays(-30)
Write-Host = $TestDate
If ($FileDate -lt $TestDate)
{
Write-Host = "Since" $file "is older than 30 Days (" $FileDate ") it will be deleted."
$UserAccountPath = "C:\\Users\\$file"
$WMIQuery = "SELECT * FROM Win32_UserProfile WHERE localpath = '$UserAccountPath'"
$UserProfile = get-wmiobject win32_userprofile | where localpath -eq c:\\users\\$file
Remove-WmiObject -InputObject "$UserProfile"
}
else
{
Write-Host = "Since File is dated less than 30 days old (" $FileDate ") it will not need to be deleted."
}
}
}
After running this I get the following error:
Remove-WmiObject : Object reference not set to an instance of an object.
At line:28 char:17
+ Remove-WmiObject -InputObject "$UserProfile"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Remove-WmiObject], NullReferenceException
+ FullyQualifiedErrorId : System.NullReferenceException,Microsoft.PowerShell.Commands.RemoveWmiObject
Any help is appreciated.
Basically, the mistake is in this line:
$UserProfile = Get-WmiObject win32_userprofile | Where localpath -EQ c:\\users\\$file
$UserProfile is null, and will always be null, because the equality comparer -eq is looking for an exact match, to put it into perspective:
'C:\some\path' -eq 'C:\\some\\path' # => False
[pscustomobject]#{
localPath = 'C:\some\path'
} | Where-Object localPath -EQ 'C:\\some\\path' # => Null
To fix this, you can do the following:
# $UserAccountPath = "C:\\Users\\$file" // This line is not needed
#
# DirectoryInfo objects have a FullName property for their Absolute Path
$UserProfile = Get-WmiObject win32_userprofile | Where-Object localpath -EQ $file.FullName
Remove-WmiObject -InputObject $UserProfile
$UserProfile = Get-WmiObject win32_userprofile | Where-Object localpath -EQ $file.FullName
$UserProfile.Delete()

I am trying to automate the config of TCPPort number 1433 on SQL Server 2016 and 2019 with a PS script

Inspired by this approach:
$pcName = $env:COMPUTERNAME
($dbmsName = Invoke-Sqlcmd -Query "SELECT ##servicename")
# Loading SQLPS environment
Import-Module SQLPS -DisableNameChecking -Force
# Initializing WMI object and Connect to the instance using SMO
($Wmi = New-Object ('Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer') $pcName)
($uri = "ManagedComputer[#Name='$pcName']/
ServerInstance[#Name='$dbmsName']/ServerProtocol[#Name='Tcp']")
# Getting settings
($Tcp = $wmi.GetSmoObject($uri))
$Tcp.IsEnabled = $true
($Wmi.ClientProtocols)
# Setting IP properties
$wmi.GetSmoObject($uri + "/IPAddress[#Name='IPAll']").IPAddressProperties[1].Value="1433"
# Save properties
$Tcp.Alter()
# Restart service
Restart-Service -Name MSSQL* -Force
Start-Sleep -s 30
Whenever I try to test with lastest version of PowerShell(5.1.17763.2090) on both SQL Servers 2016 and 2019: I get an error:
PS C:\Windows\system32> ($Tcp = $wmi.GetSmoObject($uri))
Exception calling "GetSmoObject" with "1" argument(s): "Attempt to retrieve data for object failed for ManagedComputer
'DB2T-30223'."
At line:1 char:2
+ ($Tcp = $wmi.GetSmoObject($uri))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FailedOperationException
What am I missing?
I found this on stack - Use PowerShell To Enable TCP/IP in SQL Server Configuration Manager
It seems like the same error place '+ ($Tcp = $wmi.GetSmoObject($uri))'
$pcName = $env:COMPUTERNAME
$wmi = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $pcName
$wmiinstance = $wmi.ServerInstances | Where-Object { $_.Name -eq $wmiinstancename }
$tcp = $wmiinstance.ServerProtocols | Where-Object { $_.DisplayName -eq 'TCP/IP' }
$IpAddress = $tcp.IpAddresses | where-object { $_.IpAddress -eq $IpAddress }
$tcpport = $IpAddress.IpAddressProperties | Where-Object { $_.Name -eq 'TcpPort' }

Powershell Remote Stop and Disable Service

SO Braintrust. I'm not a Powershell person, but I'm working on it. Trying to address yet another zero-day, I'm trying to build a reuseable script to remotely stop and disable the affected service. It is based on a script I got from a Microsoft MVP at (ultimately): http://portal.sivarajan.com/2010/07/stopstart-or-enabledisable-service_26.html
The prompt for the service name was added by me as well as the output information (Write-host & Add-Content lines), so I could get a results summation (the output part's not working fully, but it's the least of my concerns at the moment.).
$output = "c:\scripts\results.csv"
Add-content -path $output "======================"
Add-content -path $output "StopAndDisableService Output Start"
cls
$Cred = Get-Credential
$service = Read-Host -Prompt 'Enter Service Name" '
Import-CSV C:\Scripts\computers.csv | %
{
$computer = $_.ComputerName
Write-Host "Working on $computer"
Add-content -path $output "$computer"
$result = (Get-WmiObject win32_service -computername $computer -filter "name='$service'" -Credential $cred).stopservice()
Add-content -path $output " Stop - $result"
$result = (Get-WmiObject win32_service -computername $computer -filter "name='$service'" -Credential $cred).ChangeStartMode("Disabled")
Add-content -path $output " Disable - $result"
}
Add-content -path $output "======================"
Add-content -path $output "StopAndDisableService Output End"
when I run it, I get an error on the computer name
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'.
The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Scripts\StopAndDisableService.ps1:12 char:54
+ ... result = (Get-WmiObject win32_service -computername $computer -filter ...
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Scripts\StopAndDisableService.ps1:14 char:54
+ ... result = (Get-WmiObject win32_service -computername $computer -filter ...
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Computer.csv contains one computer name per line, no punctuation, no FQDN, just the computer name
Special thanks to #Mathias R. Jessen for his help on this. Final working code. you will have to analyze the screen output to catch any errors and see which machines it did not catch due to being offline # time of running (some output file items have been commented out since they don't work as intended)
$output = "c:\scripts\results.csv"
Add-content -path $output "======================"
Add-content -path $output "StopAndDisableService Output Start"
cls
$Cred = Get-Credential
$service = Read-Host -Prompt 'Enter Service Name" '
Import-CSV C:\Scripts\computers.csv -Header ComputerName | % {
$computer = $_.ComputerName
Write-Host "Working on $computer"
Add-content -path $output "$computer"
$result = (Get-WmiObject win32_service -computername $computer -filter "name='$service'" -Credential $cred).stopservice()
#Add-content -path $output " Stop - $result"
$result = (Get-WmiObject win32_service -computername $computer -filter "name='$service'" -Credential $cred).ChangeStartMode("Disabled")
#Add-content -path $output " Disable - $result"
}
Add-content -path $output "======================"
Add-content -path $output "StopAndDisableService Output End"
Analyzing results on the screen output, any results with
Just the machine name - means it's processed without error on that machine (success)
RPC server is unavailable means machine is offline
Cannot call a method on Null-Valued expression on line 12 or line 14 means that service doesn't exist on that machine
The results.csv output file will contain list of names of the machines this script was run against