Jump to content

Recommended Posts

How can I write this powershell command in autoit:?

$Collections = (Get-WmiObject -ComputerName siteserver  -Namespace root/SMS/site_sitecode -Query "SELECT SMS_Collection.* FROM SMS_FullCollectionMembership, SMS_Collection where name = 'hostname' and SMS_FullCollectionMembership.CollectionID = SMS_Collection.CollectionID").Name

 

Thanks

Link to post
Share on other sites

You could use "Powershell.exe -Command" switch within CMD however please note it will only return a string.  If you want to interact with the object I've always used something like the following which I wrote to add computers to a collection via third party app and then refresh the local client membership afterwards

nb: need to change $g_sSiteCode, $g_sSiteServer and $g_sCollectionResourceId values

Usage:

Script.exe -ComputerName ##ComputerName## -CollectionId P0123456

Global $g_COMErrorHandler = ObjEvent("AutoIt.Error", "_ErrFuncGlobal") ; Global COM error handler
#include <Array.au3>
#include <CmdLine.au3>

Global $g_bDebug = True
Global $g_sSiteCode = '##Site Code##' ;~ Modify
Global $g_sSiteServer = '##Primary Site Server##' ;~ Modify
Global $g_oSWbemLocator = ObjCreate("WbemScripting.SWbemLocator")
Global $g_oConnectServer = $g_oSWbemLocator.ConnectServer($g_sSiteServer, 'root\SMS\site_' & $g_sSiteCode)

Global Const $wbemFlagReturnImmediately = 0x10
Global Const $wbemFlagForwardOnly = 0x20

Global $g_sComputerName = StringStripWS(_CmdLine_SwitchValue("ComputerName"), 8)
    If $g_sComputerName = Null Then
        If $g_bDebug Then
            $g_sComputerName = @ComputerName
        Else
            Exit
        EndIf
    EndIf

Global $g_sCollectionResourceId = _CmdLine_SwitchValue("CollectionId")
    If $g_sCollectionResourceId = Null Then
        If $g_bDebug Then
            $g_sCollectionResourceId = "##UniqueId##" ;~ Modify
        Else
            Exit
        EndIf
    EndIf

_AddToCollection($g_sComputerName, $g_sCollectionResourceId)

Func _AddToCollection($_sComputerName = $g_sComputerName, $_sCollectionResourceId = $g_sCollectionResourceId)
    Local $sComputerResourceId = _GetComputerResourceId($_sComputerName)
    Local $_bResourceAdded = False
    Local $_oCollectionResourceId = $g_oConnectServer.Get("SMS_Collection.CollectionID='" & $_sCollectionResourceId & "'")
    Local $_sCollections = "SELECT * FROM SMS_CM_RES_COLL_" & $_sCollectionResourceId
    Local $_oCollections = $g_oConnectServer.ExecQuery($_sCollections)
    For $_oCollection In $_oCollections
        If $_oCollection.ResourceID = $sComputerResourceId And $_oCollection.ISDirect Then $_bResourceAdded = True
    Next
    If $_bResourceAdded = True Then
        _SccmClientAction($_sComputerName, '{00000000-0000-0000-0000-000000000021}', 'Machine Policy Retrieval and Evaluation Cycle', False)
    EndIf
    $_oSccmDirectCollectionRule = $g_oConnectServer.Get("SMS_CollectionRuleDirect" ).SpawnInstance_
        $_oSccmDirectCollectionRule.ResourceClassName = "SMS_R_System"
        $_oSccmDirectCollectionRule.ResourceID = $sComputerResourceId
    $_sAddMemberShipRule = $_oSccmDirectCollectionRule
        $_oCollectionResourceId.AddMembershipRule($_sAddMemberShipRule)
    _SccmClientAction($_sComputerName, '{00000000-0000-0000-0000-000000000021}', 'Machine Policy Retrieval and Evaluation Cycle', False)
    $_oCollectionResourceId.RequestRefresh(True)
EndFunc

Func _GetComputerResourceId($_sComputerName = $g_sComputerName)
    Local $_sTargetResource = ""
    Local $_sTargetResources = 'SELECT * FROM SMS_CM_RES_COLL_SMS00001 Where Name = "' & $_sComputerName & '"'
    Local $_oTargetResources = $g_oConnectServer.ExecQuery($_sTargetResources)
        If $_oTargetResources.Count = 0 Then Exit
    For $_oTargetResource In $_oTargetResources
        Return $_oTargetResource.ResourceID
    Next
    Return $_sTargetResource
EndFunc

Func _SccmClientAction($_sComputerName = $g_sComputerName, $_sSccmClientActionID = "{00000000-0000-0000-0000-000000000021}", $_sSccmClientActionName = "Machine Policy Retrieval and Evaluation Cycle", $_bSccmClientInventory = False)
    Local $_oWmiService
    While 1
        If Ping($_sComputerName, 1000) = 0 Then ExitLoop
        $_oWmiService = ObjGet("winmgmts:\\" & $_sComputerName & "\root\CIMV2")
            If @error Then ExitLoop
        ;Verify SMS Agent Host service exists
        $_oSccmAgentActive = $_oWmiService.ExecQuery("SELECT * FROM Win32_Service WHERE Name='CcmExec'")
            If $_oSccmAgentActive.count < 1 Then ExitLoop
        ;Delete existing full inventory if resync requested
        If $_bSccmClientInventory = True Then
            $_oSccmClientInventory = ObjGet("winmgmts:\\" & $_sComputerName & "\root\ccm\invagt")
            If @error <> 0 Then ExitLoop
            $_oSccmClientInventory.Delete('InventoryActionStatus.InventoryActionID="' & $_sSccmClientActionID & '"')
        EndIf
        ;Connect to the machine's CCM namespace
        $oCCMNameSpace = ObjGet("winmgmts:\\" & $_sComputerName & "\root\ccm")
            If @error Then ExitLoop
        ;Invoke SMS_Client.TriggerSchedule
        $oSMS_Client = $oCCMNameSpace.Get("SMS_Client")
        $oCCMAction = $oSMS_Client.Methods_("TriggerSchedule").inParameters.SpawnInstance_()
        $oCCMAction.sScheduleID = $_sSccmClientActionID
        $oCCMNameSpace.ExecMethod("SMS_Client", "TriggerSchedule", $oCCMAction)
        ExitLoop
    WEnd
EndFunc

; Global COM error handler
Func _ErrFuncGlobal($oError)
    ; Do anything here.
    ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> Global COM error handler - COM Error intercepted !" & @CRLF & _
            @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
            @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
            @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
            @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
            @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
            @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
            @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
            @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
            @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_ErrFunc

 

Link to post
Share on other sites

Thank you so much for the answer but I don't have to add computers to the collection but only check if a device is present in a collection ... I'm a beginner with script language I don't know how to get a cue, I also have to operate on the sccm of exercise a large structure and having rights that can modify objects I cannot afford to experiment .... I need a ready script that, given a hostname, tell me if it is present in the "collection X"

Link to post
Share on other sites

If you want to go the PowerShell route then recommend just using a PowerShell script aka .ps1 file,  The code above returns a list of collections to PowerShell, but you wouldn't have access to the $Collections object within Autoit.

Using class method as I posted above you could do the same thing and have access within Autoit script for example, slight modification of the script above:

Example Usage: Script.exe -ComputerName @ComputerName -CollectionId = SMS00001

Example Result: Message box will show @ComputerName has either a "direct membership" or a "query membership", if the computer is a member of the "All Systems" collection (CollectionId = SMS00001).

Global $g_COMErrorHandler = ObjEvent("AutoIt.Error", "_ErrFuncGlobal") ; Global COM error handler
Global Const $wbemFlagReturnImmediately = 0x10
Global Const $wbemFlagForwardOnly = 0x20

Global $g_bDebug = True
Global $g_sSiteCode = 'SiteCode'     ;~ Modify
Global $g_sSiteServer = 'SiteServer' ;~ Modify
Global $g_oSWbemLocator = ObjCreate("WbemScripting.SWbemLocator")
Global $g_oConnectServer = $g_oSWbemLocator.ConnectServer($g_sSiteServer, 'root\SMS\site_' & $g_sSiteCode)

Global $g_sComputerName = _CmdLine_SwitchValue("ComputerName")
    If $g_sComputerName = Null Then
        If $g_bDebug Then
            $g_sComputerName = @ComputerName
        Else
            Exit
        EndIf
    EndIf

Global $g_sCollectionResourceId = _CmdLine_SwitchValue("CollectionId")
    If $g_sCollectionResourceId = Null Then
        If $g_bDebug Then
            $g_sCollectionResourceId = "SMS00001"
        Else
            Exit
        EndIf
    EndIf

_GetCollection($g_sComputerName, $g_sCollectionResourceId)

Func _GetCollection($_sComputerName = $g_sComputerName, $_sCollectionResourceId = $g_sCollectionResourceId)
    Local $sComputerResourceId = _GetComputerResourceId($_sComputerName)
    Local $_sCollections = "SELECT * FROM SMS_CM_RES_COLL_" & $_sCollectionResourceId
    Local $_oCollections = $g_oConnectServer.ExecQuery($_sCollections)
    For $_oCollection In $_oCollections
        If $_oCollection.ResourceID = $sComputerResourceId Then MsgBox(4096, "", $_sComputerName & " has a "  & ($_oCollection.ISDirect ? "direct membership to the collection" : "query membership to the collection - ") & $g_oConnectServer.Get("SMS_Collection.CollectionID='" & $_sCollectionResourceId & "'").Name)
    Next
EndFunc

Func _GetComputerResourceId($_sComputerName = $g_sComputerName)
    Local $_sTargetResource = ""
    Local $_sTargetResources = 'SELECT * FROM SMS_CM_RES_COLL_SMS00001 Where Name = "' & $_sComputerName & '"'
    Local $_oTargetResources = $g_oConnectServer.ExecQuery($_sTargetResources)
        If $_oTargetResources.Count = 0 Then Exit
    For $_oTargetResource In $_oTargetResources
        Return $_oTargetResource.ResourceID
    Next
    Return $_sTargetResource
EndFunc

Func _CmdLine_SwitchValue($sCmdLine, $vResult = Null)
    For $i = 1 To $CmdLine[0]
        If $CmdLine[$i] = "/" & $sCmdLine Or $CmdLine[$i] = "-" & $sCmdLine Or $CmdLine[$i] = "--" & $sCmdLine Then
            If $CmdLine[0] >= $i + 1 Then
                If StringLeft($CmdLine[$i + 1], 1) = "/" Or StringLeft($CmdLine[$i + 1], 1) = "-" Or StringLeft($CmdLine[$i + 1], 2) = "--" Then
                    Return $vResult
                Else
                    Return $CmdLine[$i + 1]
                EndIf
            EndIf
        EndIf
    Next
    Return $vResult
EndFunc

; Global COM error handler
Func _ErrFuncGlobal($oError)
    ; Do anything here.
    ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> Global COM error handler - COM Error intercepted !" & @CRLF & _
            @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
            @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
            @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
            @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
            @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
            @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
            @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
            @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
            @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_ErrFunc

 

Edited by Subz
Link to post
Share on other sites

Have updated the code above, have added the _CmdLine_SwitchValue function and also the _GetComputerResourceId function which I forgot to add.

The original CmdLine UDF is found here although my version has been modified.

 

 

Link to post
Share on other sites
  • Moderators

@roccos34 I think the big (first) question to answer is - why would you want to? Best practice is not to mix scripting/programming languages unless there is a compelling reason to do so. Do you have such a reason?

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...