Invoke-WMIMethod - Throws Error Not Found - SCCM CCM Actions - powershell

Invoke-WMIMethod -ComputerName $computer -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000026}" | Out-Null
Invoke-WMIMethod -ComputerName $computer -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000027}" | Out-Null
Invoke-WMIMethod -ComputerName $computer -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-0000000000113}" | Out-Null
Invoke-WMIMethod -ComputerName $computer -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-0000000000108}" | Out-Null)
All throw Not Found Errors.
Any ideas? Are these superseded?

{00000000-0000-0000-0000-000000000026} and {00000000-0000-0000-0000-000000000027} are user specfic and seem to have been changed to a different class that is sid dependent so that you can invoke it for any user. The most common example to call them is
$sched=([wmi]"root\ccm\Policy\$sid\ActualConfig:CCM_Scheduler_ScheduledMessage.ScheduledMessageID='{00000000-0000-0000-0000-000000000026}'")
$sched.Triggers=#('SimpleInterval;Minutes=1;MaxRandomDelayMinutes=0')
$sched.Put()
Where $sid is the users SID with each - replaced with a _
You can get them for logged on users like this:
$sids = (get-wmiobject -query "SELECT UserSID FROM CCM_UserLogonEvents WHERE LogoffTime = NULL" -namespace "ROOT\ccm").UserSID.replace('-','_')
However {00000000-0000-0000-0000-000000000113} and {00000000-0000-0000-0000-000000000108} should still work with the method you used. The only reason to throw the Not Found error for those is if they are not executed with elevated admin rights, but that is the same for all the other TriggerSchedule messages as well so I don't know what the problem could be.

Related

Powershell and TPM how to manage bitlocker?

I am trying to script a powershell function manage-bde.exe (bitlocker) to add a key protector to systems without TPM. For some reason GPO is not working. I have not had any luck getting powershell to add the protector remotely. I can log on to the endpoint and use the built in wizard to encrypt and save the key to our repository but for some reason remote automated scripting eludes me. My question is really more of guidance. Can powershell only be used, to remotely manage systems with TPM? I have bitlocker enabled and encrypted on systems without but I have had to do it manually.
Start-Transcript -Path ".\bitlockertranscript.txt" -Force
foreach ($Computer in $List) {
if (test-Connection -ComputerName $Computer -Count 1 -Quiet ) {
Get-ADComputer -Identity $Computer -Property * | Select Name,OperatingSystem
Get-WmiObject -class Win32_Tpm -namespace root\CIMV2\Security\MicrosoftTpm -computername $Computer | fl IsActivated_InitialValue, IsEnabled_InitialValue, IsOwned_InitialValue
$BitLocker = Get-WmiObject -ComputerName $Computer -Namespace Root\cimv2\Security\MicrosoftVolumeEncryption -Class Win32_EncryptableVolume
$id = $BitLocker.GetKeyProtectors(3).volumekeyprotectorid | Select -First 1
manage-bde.exe -cn $Computer -protectors -adbackup c:
manage-bde.exe -on C: -cn $Computer
Invoke-GPUpdate -Target $computer
} else
{"No Connection to $Computer"
}
}
Stop-Transcript

Convert WMI call to CIM call

The code I am writing is suppose to kick off any patches currently available to a server using CIM. And I have to use CIM due to the required DCOM protocol for my network.
I'm using ` for easier viewing
The following wmi code works:
$ComputerName = 'Foo'
[System.Management.ManagementObject[]] $CMMissingUpdates = #(`
Get-WmiObject -ComputerName $ComputerName `
-Query "SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState = '0'" `
-Namespace "ROOT\ccm\ClientSDK" `
-ErrorAction Stop)
$null = (Get-WmiObject -ComputerName $ComputerName `
-Namespace "root\ccm\ClientSDK" `
-Class "CCM_SoftwareUpdatesManager" `
-List).InstallUpdates($CMMissingUpdates)
What I've made using CIM that doesn't work:
$null = (Invoke-CimMethod -CimSession $Computer.CimSession `
-Namespace 'ROOT\ccm\ClientSDK' `
-ClassName 'CCM_SoftwareUpdatesManager' `
-MethodName 'InstallUpdates').InstallUpdates($CMMissingUpdates)
Not only am I interested in a solution to my Invoke-CimMethod but how it was solved. I can't seem to determine how to view and implement the methods of classes in CIM.
Your problem is you're using two incompatible commands to translate.
Invoke-CimMethod == Invoke-WmiMethod
Get-WmiObject is not the above, however. Here's a way to accomplish what you're doing:
$ComputerName = 'Foo'
$cimArgs = #{
'Namespace' = 'Root\CCM\ClientSDK'
'ClassName' = 'CCM_SoftwareUpdatesManager'
'MethodName' = 'InstallUpdates' # returns UInt32 object; 0 = success
'Arguments' = #{
'CCMUpdates' = Get-WmiObject -Namespace Root\CCM\ClientSDK -Class CCM_SoftwareUpdate -Filter 'ComplianceState = "0"'
}
'CimSession' = New-CimSession -ComputerName $ComputerName -SessionOption (New-CimSessionOption -Protocol Dcom)
}
Invoke-CimMethod #cimArgs
The Invoke-CimMethod cmdlet takes a dictionary to pass arguments to the method. I determined the keys/values based on this documentation.
This can alternatively be found by the following:
Get-CimClass -ClassName 'CCM_SoftwareUpdatesManager' -Namespace 'Root\CCM\ClientSDK' |
ForEach-Object -MemberName CimClassMethods
Turns out it was a casting issue. Link to solution: https://www.reddit.com/r/PowerShell/comments/8zvsd8/kick_off_a_sccm_clients_install_all_available/
The final solution:
$CMMissingUpdates = #( `
Get-CimInstance -Query "SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState = '0'" `
-Namespace "ROOT\ccm\ClientSDK"
)
Invoke-CimMethod -Namespace 'ROOT\ccm\ClientSDK' `
-ClassName 'CCM_SoftwareUpdatesManager' `
-MethodName 'InstallUpdates' `
-Arguments #{
CCMUpdates = [cminstance[]]$CMMissingUpdates
}

Kill Process On List Of remote Workgroup Servers

I have a list of 5 Servers and for specific reasons they are not on the domain. The credentials among them are the same.
I am trying to remotely kill any instance of a process on the machines. For this website I have change the process to notepad.exe
I am having issues trying to determine how to successfully connect to these boxes.
I am running
$StartCheck = Get-WmiObject Win32_Process -Computer $Servers |
Where-Object { $ProcessNames -contains $_.Name }
$StartCheck | FT * -a;$StartCheck | FT * -a | out-file -FilePath $logfile -Append
and Here.
(Get-WmiObject Win32_Process -Computer $Servers |
Where-Object { $ProcessNames -contains $_.Name }).Terminate() | out-null
I am faced with the following error
Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005
(E_ACCESSDENIED))
At C:\Users\first.last\Desktop\Kill All Traffic Managers.PS1:67 char:13
+ $EndCheck = Get-WmiObject Win32_Process -Computer $Servers |
+
What is the easiest way to enter the credentials?
Add this to your script and change usernname and P#ssw0rd
$account = "username"
$PASSWORD = ConvertTo-SecureString P#ssw0rd -AsPlainText -Force
$UNPASSWORD = New-Object System.Management.Automation.PsCredential $account, $PASSWORD
Also change your
Get-WmiObject Win32_Process -Computer $Servers`
for
Get-WmiObject Win32_Process -Computer $Servers -Credential $UNPASSWORD

Invoke-WmiMethod -ArgumentList not accepting variables?

So I am very new to Powershell and I am almost certain that what I am doing is not the most efficient way of going about it. But I really want to understand why what I am doing is not working.
I am trying to trigger Configuration Manager client actions using Powershell by running the following code:
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Invoke-WmiMethod -Namespace "Root\CCM" -Class SMS_Client -Name
TriggerSchedule -ArgumentList "{00000000-0000-0000-0000-000000000042}"
}
This runs fine. But I wanted to be able to call a variable or something where all of those long codes are instead of having to put those in each time I want to change the client action. So here is where I started playing around and was unable to get anything to work.
$ApplicationDeployment = '"{00000000-0000-0000-0000000000000042}"'
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Invoke-WmiMethod -Namespace "Root\CCM" -Class SMS_Client -Name
TriggerSchedule -ArgumentList $ApplicationDeployment
}
This gives me an error. I also tried the following:
$hash = #{"ApplicationDeployment" = "{00000000-0000-0000-0000-000000000042}"}
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Invoke-WmiMethod -Namespace "Root\CCM" -Class SMS_Client -Name
TriggerSchedule -ArgumentList $hash.'ApplicationDeployment'
}
and finally
$Object = #{ApplicationDeployment = '{00000000-0000-0000-0000-000000000042}'}
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Invoke-WmiMethod -Namespace "Root\CCM" -Class SMS_Client -Name
TriggerSchedule -ArgumentList $Object.ApplicationDeployment
}
I have also tried
$($ApplicationDeployment).ArgumentList
But this gives the same error as everything else.
I would really appreciate an explanation as to why this isn't working... Thank you in advance.
Your issue is that remote machine doesn't have your variable initialized locally. You need to pass it to remote machine when executing script.
To do this, replace $Object.ApplicationDeployment with $Using:Object.ApplicationDeployment as in code below:
$Object = #{ApplicationDeployment = '{00000000-0000-0000-0000-000000000042}'}
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Invoke-WmiMethod -Namespace "Root\CCM" -Class SMS_Client -Name TriggerSchedule -ArgumentList $Using:Object.ApplicationDeployment
}

Getting StdRegProv class in Powershell

The only way I can find to get an instance of the StdRegProv WMI class in Powershell is
$StdRegProv = Get-WmiObject -List -Namespace root\default -ComputerName "my_computer" -Credential $cred | where { $_.Name -eq "StdRegProv" }
I need to go this route because I want to supply a credential. Naively I would have expected the following to work:
$StdRegProv = Get-WmiObject -Class StdRegProv -Namespace root\default -ComputerName "my_computer" -Credential $cred
but it doesn't - why can't you get at StdRegProv in this way?
As far as I understand, Get-WmiObject returns existing instances of a class. If there are no instances, you get an empty collection. (But don't quote me on this because it's just a guess - I haven't looked at Get-WmiObject code.)
Anyway, you can use:
[WMIClass]"root\default:StdRegProv"
to instantiate the class. Or, if it has to be gwmi:
Get-WmiObject -List -Namespace "root\default" -ComputerName "my_computer" `
| Where-Object {$_.Name -eq "StdRegProv"}
Source: Powershell remote registry access via WMI.