Welcome › Forums › General PowerShell Q&A › invoke-command + CIM question
- This topic has 6 replies, 2 voices, and was last updated 8 months, 3 weeks ago by
Participant.
-
AuthorPosts
-
-
May 4, 2020 at 10:38 pm #225483
If I run the below, I get the output I expect:
PowerShell1234567891011$LogonSession = Get-CimInstance -ClassName Win32_LogonSession | where-object logontype -in 2,10,11,12foreach ($ls in $LogonSession) {$lu = Get-CimAssociatedInstance -InputObject $ls -ResultClassName Win32_UserAccountif ($LU) {New-Object -TypeName PSObject -Property @{LogonSession = $LSLogonUser = $LUComputerName = $ENV:ComputerName}}}If however, I wrap that in an Invoke-Command, the Get-CimAssociatedInstance returns nothing (Meaning, if the New-Object wasn’t wrapped in an if ($LU){...} the object it returned would have ComputerName and LogonSession populated, but LogonUser would be null). Example:
PowerShell12345678910111213$Objects = invoke-command -Session $Sessions -ScriptBlock {$LogonSession = Get-CimInstance -ClassName Win32_LogonSession | where-object logontype -in 2,10,11,12foreach ($ls in $LogonSession) {$lu = Get-CimAssociatedInstance -InputObject $ls -ResultClassName Win32_UserAccountif ($LU) {New-Object -TypeName PSObject -Property @{LogonSession = $LSLogonUser = $LUComputerName = $ENV:ComputerName}}}}I cannot reason my way through why this is failing… so even if there is a way to accomplish this task another way, I’d like to understand why this way doesn’t work, in case I hit something like this again in the future.
-
This topic was modified 8 months, 3 weeks ago by
mitchvh05.
-
This topic was modified 8 months, 3 weeks ago by
-
May 5, 2020 at 12:37 am #225507
Hi Mitch,
The reason this is happening is the famous double hop issue. Basically you can use credssp, scheduled task, etc. Check the following links, the first has a nice walk through of automating allowing/configuring credssp. You can confirm this is your issue at least. It’s not allowed for good reasons, you’ll have to consider and decide.
-
May 5, 2020 at 4:35 pm #225783
Hmm… so the Get-CimInstance doesn’t bump into that restriction, but the Get-CimAssociatedInstance does? Under the hood, is Get-CimAssociatedInstance trying to create a new cim session? Or am I just missing something way simpler? Obviously, I don’t expect you to know, but if you do – that’d be awesome to find out. Thanks regardless!
-
May 5, 2020 at 7:44 pm #225804
It’s not the command per se. It’s where the information is you’re trying to retrieve. If it’s locally stored on the remote machine, you’ll have access to it. But win32_useraccount in a domain environment comes from the DC. If your remote target is a DC, it should work. If it’s not, double hop issue. Win32_useraccount will still list local accounts over remoting but not the domain accounts without providing additional credentials. See this thread for more info.
Did you confirm it worked when using CredSSP?
-
May 6, 2020 at 1:12 am #225849
This is an interesting article too. Sucks it’s “archived” like so many other good ones.
-
May 6, 2020 at 9:20 pm #226197
[Beware: Wall of Text]
For starters – thanks for helping me realize the problem. No idea how long it would have taken for me to realize Win32_UserAccount itself needed to access the DC.
I skipped trying the CredSSP; since I work for an MSP – most of our clients won’t have that setup, and I’d like this to run without making any configuration changes. I just ended up doing the Win32_UserAccount query from the local machine, then adding fields to the information I pulled from remote. It’s a bit slow, but I can work on that. At least right now, I have the beginnings of a sort-of Super “query user” which lets me poll everything in an environment. Output from my custom class looks like:
PowerShell1234567891011StartTime : 5/1/2020 8:39:13 AMLogonType : Remote InteractiveName : <MyUserName>Domain : <NetBiosDomainName>AccountType : UF_NORMAL_ACCOUNTAccountTypeDescription : Default account type that represents a typical user.AuthenticationPackage : KerberosLockout : FalseLogonSession : Win32_LogonSession (LogonId = "5165456")LogonUser : Win32_UserAccount: NetBiosDomainName\UserName (Name = "UserName", Domain = "NetBiosDomainName")ComputerName : <MyComputerName>Currently usable, but in my calling function, I’m grabbing Processes, but not using them in my class, which I’ll implement later. If you end up ever having a use for something like this, here’s the code I have so far. Second code block is my custom class.
PowerShell12345678910111213141516171819202122232425262728293031Function Get-SMAuthenticatedUser {Param([string[]]$ComputerName='localhost')for ($i=0; $i -lt $ComputerName.Count; $i++) {if ($ComputerName[$i] -like $env:COMPUTERNAME) { $ComputerName[$i] = 'localhost' }}$Objects = invoke-command -computername $ComputerName -script {$loggedOnUser = Get-CimInstance -query 'select * from Win32_LoggedOnUser'$objs = foreach ($lu in $loggedonuser) {$inst = get-ciminstance -ClassName win32_logonsession -Filter "logonid = '$($lu.dependent.logonid)'" | where-object logontype -in 10,11,12if ($inst) {$Procs = Get-CimAssociatedInstance -InputObject $inst -ResultClassName win32_Processnew-object -TypeName PSObject -Property @{LoggedOnUser = $luLogonSession = $instProcess = $ProcsComputerName = $env:COMPUTERNAME}}}write-output $Objs}$users = Get-CimInstance -class Win32_UserAccount$New = foreach ($o in $objects) {$user = $users | where-object name -like $o.LoggedOnUser.Antecedent.name[SM_LogonSession]::New($o.LogonSession,$User,$o.ComputerName)}write-output $New}PowerShell1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768Class SM_LogonSession {[datetime]$StartTime[string]$LogonType[string]$Name[string]$Domain[string]$AccountType[string]$AccountTypeDescription[string]$AuthenticationPackage[boolean]$Lockout[Microsoft.Management.Infrastructure.CimInstance]$LogonSession[Microsoft.Management.Infrastructure.CimInstance]$LogonUser[string]$ComputerNameSM_LogonSession([Microsoft.Management.Infrastructure.CimInstance]$LS, [Microsoft.Management.Infrastructure.CimInstance]$LU, [string]$ComputerName) {if (($LS | get-member).typename -contains "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_LogonSession") {if (($LU | get-member).typename -contains "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_UserAccount") {$This.LogonSession = $LS$This.LogonUser = $LU$This.ComputerName = $ComputerName$This.Build_SMLogonSession()}}}Build_SMLogonSession() {$This.SetLogonType()$This.SetAccountType()$This.Build_ObjectProperties()}Build_ObjectProperties() {$This.AuthenticationPackage = $This.LogonSession.AuthenticationPackage$This.StartTime = $This.LogonSession.StartTime$This.Name = $this.LogonUser.Name$This.Domain = $This.LogonUser.Domain$This.Lockout = $This.LogonUser.Lockout$This.SetAccountType()}SetAccountType() {switch ($This.LogonUser.AccountType) {256 { $this.AccountType = 'UF_TEMP_DUPLICATE_ACCOUNT'; $This.AccountTypeDescription='Local user account for users who have a primary account in another domain. This account provides user access to this domain only—not to any domain that trusts this domain.' }512 { $this.AccountType = 'UF_NORMAL_ACCOUNT'; $This.AccountTypeDescription = 'Default account type that represents a typical user.' }2048 { $this.AccountType = 'UF_INTERDOMAIN_TRUST_ACCOUNT'; $This.AccountTypeDescription = 'Account for a system domain that trusts other domains.' }4096 { $this.AccountType = 'UF_WORKSTATION_TRUST_ACCOUNT'; $This.AccountTypeDescription = 'Computer account for a computer system running Windows that is a member of this domain.' }8192 { $this.AccountType = 'UF_SERVER_TRUST_ACCOUNT'; $This.AccountTypeDescription = 'Account for a system backup domain controller that is a member of this domain.' }}}SetLogonType() {switch ($this.LogonSession.LogonType) {0 {$this.LogonType = ''}2 {$this.LogonType = 'Interactive'}3 {$this.LogonType = 'Network'}4 {$this.LogonType = 'Batch'}5 {$this.LogonType = 'Service'}6 {$this.LogonType = 'Proxy'}7 {$this.LogonType = 'Unlock'}8 {$this.LogonType = 'NetworkCleartext'}9 {$this.LogonType = 'NewCredentials'}10 {$this.LogonType = 'Remote Interactive'}11 {$this.LogonType = 'cachedInteractive'}12 {$this.LogonType = 'cachedRemoteInteractive'}13 {$this.LogonType = 'CachedUnlock'}default {$this.LogonType = 'Unknown'}}}} -
May 7, 2020 at 3:30 am #226254
Fantastic, thanks for sharing! If you don’t need to interact or get output from the remote script, and just need it to run. You could always use something like this. It wouldn’t be a second hop. I only list the credential part for completeness, I’m certain you can build your own.
PowerShell1234567891011121314$server = 'remoteserver'$username = Read-Host -Prompt "Enter username"$securePassword = Read-Host -Prompt "Enter password for $username" -AsSecureString$credential = [System.Management.Automation.PSCredential]::new($username,$securePassword)$params = @{Credential = $credentialComputerName = $serverClass = 'win32_process'name = 'create'ArgumentList = "powershell.exe -nop -ex bypass -file c:\scripts\somescript.ps1"}Invoke-WmiMethod @params
-
-
AuthorPosts
- The topic ‘invoke-command + CIM question’ is closed to new replies.