Getting StdRegProv class in Powershell - 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.

Related

How to change the windows account to localsystem account using Powershell command Set-Service SwitchAccount

I wan to change the windows seervice account for a service using the set-service command only and using SwitchServiceAccount Parameter but getting error that "A parameter cannot be found that matches with "SwitchServiceAccount". What is the correct switchservice command? Im using PowerShell 5.1 version.
sc.exe config "ServiceName" obj="Localsystem"
I used this method to change the service login to local system for about 40 machines. Your server list file could be .txt, .csv or some other powershell get function.
$svcobj.change relies on these these values in this sequence below. Each value here corresponds to a specific portion of the service configuration. There are 11 values and $svcobj.change needs to have all of them configured in order to work properly. Ensure you put them in the proper order, otherwise you could corrupt the service configuration. To change to LocalSystem, StartName should be changed to "LocalSystem" and all other values remain as $null.
<# WMI Win32_Service values
uint32 Change(
[in] string DisplayName,
[in] string PathName,
[in] uint32 ServiceType,
[in] uint32 ErrorControl,
[in] string StartMode,
[in] boolean DesktopInteract,
[in] string StartName,
[in] string StartPassword,
[in] string LoadOrderGroup,
[in] string LoadOrderGroupDependencies[],
[in] string ServiceDependencies[]
);
#>
#Configure Runas LocalSystem
$svcname = "WindowsService"
foreach ($source in get-content "Some_Path_to_Server_List") {
$source
$svcobj = Get-WmiObject -ComputerName $source -Class Win32_Service -Filter "Name='$svcname'"
$svcobj.StopService | out-null
$svcobj.Change($null,$null,$null,$null,$null,$null,"LocalSystem",$null,$null,$null,$null) | out-null
$svcobj.StartService | out-null
Get-WmiObject -ComputerName $source -Class Win32_Service -Filter "Name='$svcname'"
}
Or you can use this code below to run as a specific user with username and password. $svccred prompts for username and password and stores it encrypted in memory.
#Configure Runas AD User
$svccred = Get-Credential -Message "Enter Service Account Credentials"
$svcname = "WindowsService"
foreach ($source in get-content "Some_Path_to_Server_List") {
$source
$svcobj = Get-WmiObject -ComputerName $source -Class Win32_Service -Filter "Name='$svcname'"
$svcobj.StopService | out-null
$svcobj.Change($null,$null,$null,$null,$null,$null,$svccred.Username,$svccred.Password,$null,$null,$null) | out-null
$svcobj.StartService | out-null
Get-WmiObject -ComputerName $source -Class Win32_Service -Filter "Name='$svcname'"
}
According to the docs, the Set-Service command does not have such a parameter. (You can also use Get-Help Set-Service -Full to see the available parameters with explanation and examples.)
In PowerShell Core (v6+) you can set the service credentials with the -Credentials parameter:
Set-Service -Name Schedule -Credential $credential
In PowerShell 5.1 try a solution from this SO post:
$service = Get-WmiObject win32_service -Filter "name='YourService'"
$service.Change($null,$null,$null,$null,$null,$null,"user","password")
or this:
Get-CimInstance win32_service -filter “name=’some_service_name'” | Invoke-CimMethod -Name Change -Arguments #{StartName=”LocalSystem”}
#Yogesh
This cannot work :
Get-CimInstance win32_service -filter "name='DIAHostService'" | Invoke-CimMethod `
-Name Change -Arguments #{StartName="LocalSystem"}
Because Change method needs to have the start password to be set even there is none (if StartName is defined), so this call shall succeed :
Get-CimInstance win32_service -filter "name='DIAHostService'" | Invoke-CimMethod `
-Name Change -Arguments #{StartName="LocalSystem";StartPassword=""}

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

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

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.

Get-WmiObject Win32_networkadapterconfiguration

I'm trying to use WMI to retrieve network adapter information on remote servers.
I've ran a few Get-WmiObject commands with various degrees of success.
This line works fine:
Invoke-Command $serverName -ScriptBlock {Get-WmiObject
Win32_networkadapterconfiguration | where {$_.Index -eq 7}}
When I try to introduce a variable to the command it returns nothing:
$Variable = 7
Invoke-Command $serverName -ScriptBlock {Get-WmiObject
Win32_networkadapterconfiguration | where {$_.Index -eq $Variable}}
Any idea why the command with the variable would fail?

Powershell: Get-WmiObject cannot run asJob in loop

I want to sometimes check some info from our servers in domains. In this example, I am trying to remotely get windows versions (just one server, currently without loop):
$cr=Get-Credential "domain\adm_user"
$computer="serverA"
Invoke-Command { Get-WmiObject -Class Win32_OperatingSystem -Namespace root/cimv2 -Computer $computer -Credential $cr | Format-List -Property Name, OSArchitecture, SerialNumber} -AsJob -ComputerName .
Get-Job | Wait-Job
Get-Job | Receive-Job
Output:
Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
Seems, that scriptblock {} cannot see variable $computer.
When I replace variable -computer $computer to name of server, it is working.
For variable expansion inside Invoke-Command use a param block and specify arguments:
$computer = 'localhost'
Invoke-Command {param($computer) Get-WmiObject Win32_OperatingSystem -Computername $computer } -ArgumentList $computer
Working on PS v5.