Skip to Content

Use SAP GUI Scripting with Native PowerShell

A few days ago I presented here the new version of Scripting Tracker. The new version supports now native PowerShell code generating.

Here an example of a PowerShell script from a logon process.

/wp-content/uploads/2016/03/001_909030.jpg

You see the SAP GUI for Windows screen and the recorded script inside Scripting Tracker. With Scripting Tracker it is seamless possible to switch in the PowerShell ISE and here you find the complete code. Now you can use all the possibilities of the ISE like single step debugging or examination of variables.

Scripting Tracker uses a COM bridge for the communication with SAP GUI Scripting, which I presented here. On this way it is possible to generate code which is nearly similar to well known VBScript.

Here an example of an activity in an tree control in VBScript:

session.findById(“wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell”).expandNode “0000000003”

session.findById(“wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell”).selectedNode = “0000000004”

Here the same example in PowerShell:

$ID = Invoke-Method $session “findById” @(“wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell”)

Invoke-Method $ID “expandNode” @(“0000000003”)

$ID = Invoke-Method $session “findById” @(“wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell”)

Set-Property $ID “selectedNode” @(“0000000004”)

The comparisation shows that code in VBScript contains one line for one activity and PowerShell two lines. The code generation creates for findById one call of Invoke-Method and with the returned ID it calls the next activity e.g. like expandNode.

/wp-content/uploads/2016/03/002_909031.jpg

In some cases the code generation creates well known code like

$ID.elementAt(3).width = 19

which should sets the width of the third column of the table control.

But the method elementAt doesn’t work in this context, it is necessary to replace it with Item like

$ID.Item(3).width = 19

which works perfectly.

/wp-content/uploads/2016/03/003_909143.jpg

Since version 5, which I presented here, offers PowerShell new language features like classes.

It has many advantages more to use PowerShell instead VBScript with SAP GUI Scripting:

  1. PowerShell is the actual Scripting language in Windows environments.
  2. It is available on all Windows systems without further installations.
  3. It is in further development.
  4. Its security mechanisms are technically mature.
  5. PowerShell offers an Integrated Scripting Environment (ISE) e.g. for single step debugging.
  6. etc.
4 Comments
You must be Logged on to comment or reply to a post.
  • Hi, sorry to bother you, but this is my first time working with SAP APIs. My objective is to create a PowerShell script that takes a username as input and sets the following fields within SAP GUI:

    Logon Data > Validity Period

    • Valid from
    • Valid through

    and lastly to lock the account.

    If it’s not too much to ask, would you mind showing me what the PowerShell code for this would look like, including how to have my PowerShell script connect to SAP to execute those commands in the first place?

    Sorry if these questions seem trivial / ridiculous, I’m used to working with PowerShell cmdlets from Microsoft that are very intuitive / self-explanatory that also come with documentation and examples.

    • Hello Jeffrey,

      welcome in the SAP Community.

      Here a PowerShell script recorded with Scripting Tracker:

      #-Call TAC SU01---------------------------------------------------------
      $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[0]/okcd");
      Set-Property $ID "text" @("/nSU01");
      $ID = Invoke-Method $session "findById" @("wnd[0]");
      Invoke-Method $ID "sendVKey" @(0);
      #-Set user name---------------------------------------------------------
      $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtSUID_ST_BNAME-BNAME");
      Set-Property $ID "text" @("BCUSER");
      #-Press change button---------------------------------------------------
      $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[1]/btn[18]");
      Invoke-Method $ID "press";
      #-Choose logondata tab--------------------------------------------------
      $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO");
      Invoke-Method $ID "select";
      #-Set valid from date (GLTGV = Gueltig von)-----------------------------
      $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO/ssubMAINAREA:SAPLSUID_MAINTENANCE:1101/ctxtSUID_ST_NODE_LOGONDATA-GLTGV");
      Set-Property $ID "text" @("01.03.2019");
      #-Set valid through (GLTGB = Gueltig bis)-------------------------------
      $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO/ssubMAINAREA:SAPLSUID_MAINTENANCE:1101/ctxtSUID_ST_NODE_LOGONDATA-GLTGB");
      Set-Property $ID "text" @("31.03.2019");
      #-Press save button-----------------------------------------------------
      $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[0]/btn[11]");
      Invoke-Method $ID "press";

      I call TAC SU01 and fill the fields you described and press save button.

      Here a snippet to login, replace the user, password and language with yours.

      $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME");
      Set-Property $ID "text" @("BCUSER");
      $ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE");
      Set-Property $ID "text" @("minisap");
      $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU");
      Set-Property $ID "text" @("DE");
      $ID = Invoke-Method $session "findById" @("wnd[0]");
      Invoke-Method $ID "sendVKey" @(0);

      Best regards
      Stefan

       

      • Awesome, thanks so much!

        I’m going to give an example of what I think the full script would look like, using standard PowerShell variables:

        $session = '???'
        $server = 'SU01'
        $adminUsername = 'admin'
        $adminPassword = 'p@ssw0rd'
        $language = 'US'
        $username = 'user'
        $fromDate = '01.03.2019' #DD.MM.YYYY
        $throughDate = '31.03.2019' #DD.MM.YYYY
        
        #-login with admin credentials
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME");
        Set-Property $ID "text" @($adminUsername);
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE");
        Set-Property $ID "text" @($adminPassword);
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU");
        Set-Property $ID "text" @($language);
        $ID = Invoke-Method $session "findById" @("wnd[0]");
        Invoke-Method $ID "sendVKey" @(0);
        #-Call TAC SU01---------------------------------------------------------
        $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[0]/okcd");
        Set-Property $ID "text" @("/n$server");
        $ID = Invoke-Method $session "findById" @("wnd[0]");
        Invoke-Method $ID "sendVKey" @(0);
        #-Set user name---------------------------------------------------------
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtSUID_ST_BNAME-BNAME");
        Set-Property $ID "text" @($username);
        #-Press change button---------------------------------------------------
        $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[1]/btn[18]");
        Invoke-Method $ID "press";
        #-Choose logondata tab--------------------------------------------------
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO");
        Invoke-Method $ID "select";
        #-Set valid from date (GLTGV = Gueltig von)-----------------------------
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO/ssubMAINAREA:SAPLSUID_MAINTENANCE:1101/ctxtSUID_ST_NODE_LOGONDATA-GLTGV");
        Set-Property $ID "text" @($fromDate);
        #-Set valid through (GLTGB = Gueltig bis)-------------------------------
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO/ssubMAINAREA:SAPLSUID_MAINTENANCE:1101/ctxtSUID_ST_NODE_LOGONDATA-GLTGB");
        Set-Property $ID "text" @($throughDate);
        #-Press save button-----------------------------------------------------
        $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[0]/btn[11]");
        Invoke-Method $ID "press";

        Am I putting the variables in the correct places? Does my example script cover all 3 of my objectives from my original comment?

        Also, a few final questions:

        • What goes in the “session” variable?
        • Is ‘US’ the code for English in the United States?
        • Where would I find my server name (in your example you used “SU01”)?
        • Does this script also lock the account at the end? I see commented sections for setting the from and through dates, but not for locking the account.
        • Do I need to do anything else before running this code (install any cmdlets / dependencies, etc)?

        Thanks again for all your help!

  • Hello Jeffrey,

    here the total script to login to an SAP system:

    #-Begin-----------------------------------------------------------------
    
      #-Includes------------------------------------------------------------
        ."$PSScriptRoot\COM.ps1";
    
      #-Main----------------------------------------------------------------
        $SapGuiAuto = Get-Object( , "SAPGUI");
        If ($SapGuiAuto -isnot [__ComObject]) {
          Exit;
        }
    
        $application = Invoke-Method $SapGuiAuto "GetScriptingEngine";
        If ($application -isnot [__ComObject]) {
          Free-Object $SapGuiAuto;
          Exit;
        }
    
        $connection = Get-Property $application "Children"@(0);
        If ($Null -eq $connection) {
          Free-Object $SapGuiAuto;
          Exit;
        }
    
        $session = Get-Property $connection "Children"@(0);
        If ($Null -eq $session) {
          Free-Object $SapGuiAuto;
          Exit;
        }
    
    $UserID = "BCUSER";
    $PWD = "minisap";
    
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-MANDT");
    Set-Property $ID "text" @("099");
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME");
    Set-Property $ID "text" @($UserID);
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE");
    Set-Property $ID "text" @($PWD);
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU");
    Set-Property $ID "text" @("EN");
    $ID = Invoke-Method $session "findById" @("wnd[0]");
    Invoke-Method $ID "sendVKey" @(0);
    
    
        Free-Object $SapGuiAuto;
    
    #-End-------------------------------------------------------------------

    You need also the include file COM.ps1 which stores some COM procedures.

    The session variable is from type __COMObject and contains the dispatcher to all methods and attributes of the SAP GUI API for the session.

    In my opinion is EN the correct language code.

    No, SU01 is a transaction code, not a server name. You can find detailed information about your system in menu System > Status…

    Yes, you need the include and a few lines of code, look at my example.

    Best regards
    Stefan