Jump to content

Recommended Posts

Posted

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

Posted

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

 

Posted

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"

Posted (edited)

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
Posted (edited)

which UDF CmdLine.au3 should I use? (where do I download 

can you send me (or link) the UDF you used?

Edited by roccos34
Posted

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.

 

 

  • Moderators
Posted

@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!

Posted (edited)

@JLogan3o13 
I agree in fact I wanted to do the same thing in pure autoit which I know slightly better than powershell
 

Edited by roccos34

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...