How do I attach a debugger to a process using Invoke-WmiMethod? - powershell

I have a process already running on a remote computer and I'd like to attach a debugger to it. I would like to use Invoke-WMIMethod so that when I disconnect from that remote session, the debugger will remain attached to the process in the background.
So far I have:
$Qry = "Select * from Win32_Process where ProcessID like $ID"
$CimIO = Get-WMIObject -Query $Qry
Invoke-WMIMethod -InputObject $CimIO -Class Win32_Process -Name AttachDebugger -AsJob
And I'm getting the following error:
Invoke-WmiMethod : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:1
+ Invoke-WmiMethod -InputObject $CimIO -Class Win32_process -Name Attac ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-WmiMethod], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.InvokeWmiMethod
Am I on the right track? When I try other Methods from Win32_Process (like GetOwner), I get the same error message. What's going on here?
EDIT:
Perhaps I am going about this all wrong: My understanding was that the query would return a pointer to the running process which could then be used as an input object to Invoke-WmiMethod.
Debug-Process requires that a separate debugger already be downloaded and installed on the machine whereas "AttachDebugger" as a method is installed by default (at least I'm assuming since it was on a fresh copy of Windows 10). The reason why I want to use built-in methods only is because I would like this script to be usable in a production environment where I will not have control over what's installed on the computers.
I found the method by running the script found here which found the method residing in Win32_Process. I went with Invoke-WmiMethod because when -AsJob is invoked, it creates a job locally on the remote computer where the process I'm sending to a debugger resides.
Thank you for the help and I'm sorry for the confusion: this is part of my first powershell script.
The use case is follows:
In a SIEM environment the user sees a program on the network acting suspicious. The user then remotely logs into the victim computer and freezes the suspicious thread by sending it to a debugger. The user then logs out and will get back to analyzing the thread later. The thread will remain frozen until that time.

I've personally never tried or had a reason to try this use case.
However, AsJob is used for long running tasks. You are only querying to get a listing of a single Process ID and once that listing is provided, the job is done / stopped / completed.
There is nothing to attach to. Lastly, where are you getting this method --- AttachDebugger -- from?
There is no such method using the Get-WmiObject or Invoke-WmiMethod cmdlet parameters. That is what the error is about
Why are you not just using the built-in cmdlet for this effort.
# get function / cmdlet details
(Get-Command -Name Debug-Process).Parameters
Get-help -Name Debug-Process -Examples
Get-help -Name Debug-Process -Full
Get-help -Name Debug-Process -Online

Related

Tigger installation in software center using SCCM 2012 & Powershell

I would need some directions where to look for an solution.
I need to trigger install on a few programs in SCCM 2012 software center on Windows 10 clients through Powershell. I guess some of those are User Based Packages(not sure about this at all) but when i run the following.
$Application = Get-CimInstance -Namespace "root\ccm\clientSDK" -ClassName CCM_application
$Application
I get some of the programs, but many of them is missing.
If I open software center and click install on any programs manually it will then appear when I use the command above.
I've been reading about CCM-Application I found something about you only get device based packages.
I cannot access any servers so accessing CMApplicationCatalog is not possible. Like in the links below.
Trigger available application catalog
install-user-based-application-or-packages
In my case using CCM_Application Client WMI Class seems to be hard, I've not found any other solutions then creating New-WebServiceProxy to do this, and I´m not allowed/have permissions to.
I've tried to get the needed parameters for one of the programs that don't appear with the code above from a computer I've installed it on through Software Center.
When I try to run it with the needed parameters on an new installed computer.
$Program = #{"EnforcePreference"=[UInt32]0
"Id" = [String]"ScopeId_MyScopeID, will leave this out for company rules."
"IsMachineTarget" = [Boolean]$false
"IsRebootIfNeeded" = [Boolean]$false
"Priority" = [String]"High"
"Revision" = [String]"7"
}
Invoke-CimMethod -Namespace Root\ccm\clientSDK -ClassName CCM_application -MethodName "Install" -Arguments $Program
I then get error below
Invoke-CimMethod : Not found At line:1 char:1
+ Invoke-CimMethod -Namespace Root\ccm\clientSDK -ClassName CCM_applica ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Root\ccm\clientSDK:CCM_application:String) [Invoke-CimMethod],
CimException
+ FullyQualifiedErrorId : HRESULT 0x80041002,Microsoft.Management.Infrastructure.CimCmdlets.InvokeCimMethodCommand
Maybe I am doing something wrong or what I am trying to do is not possible.
I've also tried uiresource.uiresourcemgr but It returns empty.
I used this much in SCCM 2007 and it worked great. But now it's not giving me anything.
$RunAdvProg = New-Object -ComObject uiresource.uiresourcemgr
$RunAdvProg.GetAvailableApplications();
With this said, Is there anyway way around this or does it exist another function/Method from another class or DLL?

Early filtering within the root\ccm\cliensdk namespace

I recently wrote a script that updates registry values on remote desktops after checking, for instance, that a certain application, MyApp, is properly installed.
The aforementioned application is installed/deployed by SCCM (2012, not R2 for the moment).
In the process of optimizing the script, I wanted to change the test of the install state of MyApp (from late to early filtering).
So far, no luck and so far, no explanation either.
I can't properly understand why it seems not possible to do some early filtering with the following command :
gwmi -ComputerName myserver -Namespace root\ccm\clientsdk -query "select * from ccm_application where Fullname='MyApp'"
Of course, nor can we use :
gwmi -ComputerName myserver -Namespace root\ccm\clientsdk -class ccm_application -filter "Fullname='MyApp'"
Late filtering, of course, works but I wanted (and expected) early filtering to work, especially since I am checking the Install state of an app for quite a lot of remote desktops.
Of course, I do know that I could (can) use SCCM for that purpose (executing a script only if ...) but that still does not explain why I can't do early filtering.
Whenever I try to query that class with my installation while specifying either properties or a filter, I get the error "Provider is not capable of the attempted operation". It doesn't matter if I use Get-WmiObject or Get-CimInstance.
I get the same error when I run this:
PS C:\> WMIC.EXE /NAMESPACE:\\root\ccm\clientsdk PATH ccm_application GET FullName
Node - <SERVERNAME>
ERROR:
Description = Provider is not capable of the attempted operation
PS C:\> wmic /NAMESPACE:\\root\ccm\clientsdk PATH ccm_application WHERE "FullName='Java 32-bit'"
Node - <SERVERNAME>
ERROR:
Description = Provider is not capable of the attempted operation
Although this works just fine:
WMIC.EXE /NAMESPACE:\\root\ccm\clientsdk PATH ccm_application
Seems like a limitation of the provider then, not a problem with your code. -Filter and -Property don't work by design.
Note that I am using 2012 R2 SP1 (5.00.8239.1000), so this may not perfectly apply. However, it seems unlikely that they would remove the functionality from the provider moving from 2012 to 2012 R2.

Return code and status from PowerShell command

I'm running the following command from within a Microsoft System Centre Orchestrator PowerShell activity:
Install-WindowsFeature -ConfigurationFilePath C:\DeploymentConfigTemplate.xml -ComputerName ServerXYZ
the command isn't doing what it's supposed to do, and I want to be able to return if the command was successful or not, and any error message if possible. Ignore the fact it's running in Orchestrator, as I'm more concerned about the PowerShell question. When I run the command from ISE it does what it's supposed to do, that's why I want to see what is returned from PowerShell.
Thanks.
It's hard to know what may be happening without more context. The following will record any errors encountered in an xml file that you can import later with import-clixml:
Install-WindowsFeature -ConfigurationFilePath C:\DeploymentConfigTemplate.xml -ComputerName ServerXYZ
IF (!($?)) {
$error[0] | export-clixml C:\myerror.xml
}
This solves my problem:
$Result = Install-WindowsFeature -Name SNMP-Service -IncludeAllSubFeature -IncludeManagementTools
Write-Host $Result.ExitCode

Delete a SCCM collection from the command-line

When using the UI (SCCM 2012), to be able to delete a collection (let's say CollA), you need first to ensure it is not linked by any rule to another (let's say CollB, etc..) such as :
CollB includes CollA
CollC excludes CollA
When dealing with a lot of collections, deleting a collection can be time-consuming. For that reason, I have created a script,
usable remotely to avoid the need to connect through RDP
which checks that CollA has no rule left (even if that is not a problem if we want to delete CollA)
which checks if CollA is "linked" to other collections (include or exclude rules)
which deletes any rule found (between CollB and CollA, between CollC and CollA)
I'm stuck now for I can not find a way to delete CollA.
For authentication matters and for remote purpose, I use a lot Powershell and WMI.
$CollA=Get-WmiObject -computername servername -namespace root\sms\site_111 -credential $cred -query "select * from SMS_Collection where Name='Tartempion'"
$CollA.get()
At that point, I found a method Delete(), which when I try to use it, it gives me :
Exception calling "Delete" with "0" argument(s): "Generic failure "
At line:1 char:1
+ $coll.delete()
+ ~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
If that is the method that I should use, what are the arguments to be passed ?
EDIT 1
As pointed by theMadTechnician, the SCCM collection, once retrieved in $CollA, a System.Management.ManagementObject.
I should, as described in the MSDN pages, be able to use the following method :
Delete() > produces the error mentioned above
Delete(DeleteOptions) > I can not find the specs for the required options
Delete(ManagementOperationObserver) > I can not find the specs for the required options
To ensure I properly understood the MSDN page regarding *.Delete(), i tried (successfully) the following:
PS C:\> Set-WmiInstance -Class win32_environment -argument #{Name="testvar";VariableValue="testvalue";UserName="<SYSTEM>"}
PS C:\> (gwmi -class win32_environment -filter "Name='testvar'").gettype()
PS C:\> (gwmi -class win32_environment -filter "Name='testvar'").delete()
EDIT 2
The fact is that when deleting a SCCM collection through the console, the collection is not the only thing removed from the inventory : the assignments for instance, are too removed. It reminds of the CASCADE switch when dealing with MySQL or ORACLE. Maybe what I'm trying to do is not possible
without using the console
without using the SCCM cmdlets
If it can not be done that way, I just need to be sure.
EDIT 3
After some maturing, I am starting to wonder if it could be a authorization matter. I mean, the account I am using with the "-credential" switch or when connecting to the server, to open a SCCM console, allows me to create/update/delete collection but, for instance, it does not allow me to delete a device. I would expect the error message to be different but who knows ?
More or less about the same matter (sorry for the digression), trying to remove a device from the commandline, I found this and I have the same error message (see above). If it works for others and not me, could it be authorization related ?
EDIT 4
I requested a service account with more "privileges" than I have with my technical account.
I tested and I have the same error. I am putting aside the authorization hypothesis.
I just tested this in our SCCM 2012 environment by using the following command:
$CollA=Get-WmiObject -computername servername -namespace root\sms\site_111 -query "select * from SMS_Collection where Name='Tartempion'"
Basically, take the -credential out of there. Does it work now?
You could potentially setup a script like so:
#if the delete command fails...
if(!($?))
{
$limitedcollectionName = $colla.LimitedCollectionName
$limitedcollection = Get-WmiObject -computername servername -namespace root\sms\site_111 -query "select * from SMS_Collection where Name=`'$limitedcollectionname`'"
$limitedcollectionname.delete()
}

Get status of a process started by Invoke-WmiMethod

New to PowerShell, but loving the fact that I can do so much so quickly so far :)
Anyways, I am starting a remote process in a PowerShell script thusly:
$compname = "MY-PC"
$myinstallcmd = "c:\install\myprog.exe /s"
$proc = Invoke-WmiMethod -class Win32_Process -name Create -ArgumentList ($myinstallcmd) -ComputerName $compname
On most of the PCs I've tried, the Invoke-WmiMethod cmdlet works fine, but on one PC, it's hanging. What I'm now looking to do is get the status of the running process, and if it's hung up, kill it and log the kill, and then move on.
I did find a possible method to do this in the post
Starting a process remotely in Powershell, getting %ERRORLEVEL% in Windows - however, when I try to do the Register-WmiEvent on the process $proc.ProcessId, I'm getting the dreaded 0x80070005 (E_ACCESSDENIED) error... I am running the PowerShell host as domain admin.
Can anyone please suggest a way that I can get a status on the process I've started, and be able to take an action based on the status?
Thanks!
Update: I guess you are missing remote system credentials:
Try passing the credentials to remote system using -Credential parameter. This takes a PSCredential Object and hence you can do something like:
$cred = Get-Credential
Register-WMIEvent -Credential $cred <and other parameters here>
See if any of the following resolves the access denied error:
0x80070005 (DCOM ACCESS_DENIED)
This error occurs when the connected user is not recognized or is restricted in some fashion by the remote server (for example, the user might be locked out). This happens most often when accounts are in different domains. Recent changes to WMI security can also cause this error to occur:
Blank passwords, formerly permitted, are not allowed in Windows XP and Windows Server 2003.
WMI does not allow asynchronous callbacks to a Windows 98 client. A call like SWbemServices.ExecNotificationQueryAsync from a Windows 98 computer to a Windows XP computer will result in an Access Denied error returned to the Windows 98 machine.
The DCOM configuration access setting might have been changed.
If the target computer is running Windows XP, the Forceguest value under the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa might be set to force the Guest account off (value is zero).
Source: http://technet.microsoft.com/en-us/library/ee692772.aspx