Skip to Content

How to Call BAPI Function Modules with PowerShell via NCo

I presented here the possibility to use PowerShell via dotNET Connector (NCo) with SAP. Also I presented here two auxiliary functions for an easier using of PowerShell via dotNET Connector (NCo) with SAP.

Here now a short description with two examples how to call BAPI function modules (FM) with PowerShell and NCo. I use the FM BAPI_USER_CREATE1 and BAPI_USER_DELETE. In comparisaon to a normal function call we use also the FM BAPI_TRANSACTION_COMMIT to do an external commit. Also we use an additional context to start a stateful call sequence, to bind the destination’s connection pool with the current thread of execution, with BeginContext and EndContext.

Here the first example how to create the user MYUSER:

#-Begin-----------------------------------------------------------------

  #-Sub Load-NCo--------------------------------------------------------
    Function Load-NCo {

      $ScriptDir = $PSScriptRoot

      $Size = [System.IntPtr]::Size
      if ($Size -eq 4) {
        $Path = $ScriptDir + "\x86\"
      }
      elseif ($Size -eq 8) {
        $Path = $ScriptDir + "\x64\"
      }

      [Reflection.Assembly]::LoadFile($Path + "sapnco.dll") > $Null
      [Reflection.Assembly]::LoadFile($Path + "sapnco_utils.dll") > $Null

    }

  #-Function Get-Destination--------------------------------------------
    Function Get-Destination {

      #-Connect paramters-----------------------------------------------
        $cfgParams = New-Object SAP.Middleware.Connector.RfcConfigParameters
        $cfgParams.Add("NAME", "TEST")
        $cfgParams.Add("ASHOST", "ABAP")
        $cfgParams.Add("SYSNR", "00")
        $cfgParams.Add("CLIENT", "001")
        $cfgParams.Add("USER", "BCUSER")

        $SecPasswd = Read-Host -Prompt "Passwort" -AsSecureString
        $ptrPasswd = [Runtime.InteropServices.Marshal]::SecureStringToBStr($SecPasswd)
        $Passwd = [Runtime.InteropServices.Marshal]::PtrToStringBStr($ptrPasswd)
        $cfgParams.Add("PASSWD", $Passwd)

      Return [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($cfgParams)

    }

  #-Sub Invoke-SAPFunctionModule----------------------------------------
    Function Invoke-SAPFunctionModule {

      $destination = Get-Destination

      #-Metadata--------------------------------------------------------
        Try {
          [SAP.Middleware.Connector.IRfcFunction]$bapiCreateUser =
            $destination.Repository.CreateFunction("BAPI_USER_CREATE1")
          [SAP.Middleware.Connector.IRfcFunction]$bapiTransactionCommit =
            $destination.Repository.CreateFunction("BAPI_TRANSACTION_COMMIT")
        }
        Catch [SAP.Middleware.Connector.RfcBaseException] {
          Write-Host "Metadaten-Fehler"
          Break
        }

      #-Set import parameters-------------------------------------------
        $bapiCreateUser.SetValue("USERNAME", "MYUSER")
        [SAP.Middleware.Connector.IRfcStructure]$imPassword =
          $bapiCreateUser.GetStructure("PASSWORD")
        $imPassword.SetValue("BAPIPWD", "initial")
        [SAP.Middleware.Connector.IRfcStructure]$imAddress =
          $bapiCreateUser.GetStructure("ADDRESS")
        $imAddress.SetValue("FIRSTNAME", "My")
        $imAddress.SetValue("LASTNAME", "User")
        $imAddress.SetValue("FULLNAME", "MyUser")

      #-Open context----------------------------------------------------
        [SAP.Middleware.Connector.RfcSessionManager]::BeginContext($destination) > $Null

      #-Call function module--------------------------------------------
        Try {
          #-Create user-------------------------------------------------
            $bapiCreateUser.Invoke($destination)
          [SAP.Middleware.Connector.IRfcTable]$return =
            $bapiCreateUser.GetTable("RETURN")
          ForEach ($line in $return) {
            Write-Host $line.GetValue("TYPE") "-" $line.GetValue("MESSAGE")
          }
          #-Commit------------------------------------------------------
            $bapiTransactionCommit.Invoke($destination)
        }
        Finally {
          #-Close context-----------------------------------------------
            [SAP.Middleware.Connector.RfcSessionManager]::EndContext($destination) > $Null
        }

    }

  #-Sub Main------------------------------------------------------------
    Function Main () {
      If ($PSVersionTable.PSVersion.Major -ge 3) {
        Load-NCo
        Invoke-SAPFunctionModule
      }
    }

  #-Main----------------------------------------------------------------
    Main

#-End-------------------------------------------------------------------

Here now the second example how to delete the user MYUSER:

#-Begin-----------------------------------------------------------------

  #-Sub Load-NCo--------------------------------------------------------
    Function Load-NCo {

      $ScriptDir = $PSScriptRoot

      $Size = [System.IntPtr]::Size
      if ($Size -eq 4) {
        $Path = $ScriptDir + "\x86\"
      }
      elseif ($Size -eq 8) {
        $Path = $ScriptDir + "\x64\"
      }

      [Reflection.Assembly]::LoadFile($Path + "sapnco.dll") > $Null
      [Reflection.Assembly]::LoadFile($Path + "sapnco_utils.dll") > $Null

    }

  #-Function Get-Destination--------------------------------------------
    Function Get-Destination {

      #-Connect parameters----------------------------------------------
        $cfgParams = New-Object SAP.Middleware.Connector.RfcConfigParameters
        $cfgParams.Add("NAME", "TEST")
        $cfgParams.Add("ASHOST", "ABAP")
        $cfgParams.Add("SYSNR", "00")
        $cfgParams.Add("CLIENT", "001")
        $cfgParams.Add("USER", "BCUSER")

        $SecPasswd = Read-Host -Prompt "Passwort" -AsSecureString
        $ptrPasswd = [Runtime.InteropServices.Marshal]::SecureStringToBStr($SecPasswd)
        $Passwd = [Runtime.InteropServices.Marshal]::PtrToStringBStr($ptrPasswd)
        $cfgParams.Add("PASSWD", $Passwd)

      Return [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($cfgParams)

    }

  #-Sub Invoke-SAPFunctionModule----------------------------------------
    Function Invoke-SAPFunctionModule {

      $destination = Get-Destination

      #-Metadata--------------------------------------------------------
        Try {
          [SAP.Middleware.Connector.IRfcFunction]$bapiDeleteUser =
            $destination.Repository.CreateFunction("BAPI_USER_DELETE")
          [SAP.Middleware.Connector.IRfcFunction]$bapiTransactionCommit =
            $destination.Repository.CreateFunction("BAPI_TRANSACTION_COMMIT")
        }
        Catch [SAP.Middleware.Connector.RfcBaseException] {
          Write-Host "Metadaten-Fehler"
          Break
        }

      #-Set import parameters-------------------------------------------
        $bapiDeleteUser.SetValue("USERNAME", "MYUSER")

      #-Open context----------------------------------------------------
        [SAP.Middleware.Connector.RfcSessionManager]::BeginContext($destination) > $Null

      #-Call function module--------------------------------------------
        Try {
          #-Delete user-------------------------------------------------
            $bapiDeleteUser.Invoke($destination)
          [SAP.Middleware.Connector.IRfcTable]$return =
            $bapiDeleteUser.GetTable("RETURN")
          ForEach ($line in $return) {
            Write-Host $line.GetValue("TYPE") "-" $line.GetValue("MESSAGE")
          }
          #-Commit------------------------------------------------------
            $bapiTransactionCommit.Invoke($destination)
        }
        Finally {
          #-Close context-----------------------------------------------
            [SAP.Middleware.Connector.RfcSessionManager]::EndContext($destination) > $Null
        }

    }

  #-Sub Main------------------------------------------------------------
    Function Main () {
      If ($PSVersionTable.PSVersion.Major -ge 3) {
        Load-NCo
        Invoke-SAPFunctionModule
      }
    }

  #-Main----------------------------------------------------------------
    Main

#-End-------------------------------------------------------------------

These examples shows also how to use structures and tables in the import and export parameters.

PowerShell offers a lot of possibilities and among the shadow of the circumstance of the end of support of VBScript in a shorter distant future – first signs look here – seems it better to look for an alternative. In my case offers PowerShell all the things to replace VBScript.

Be the first to leave a comment
You must be Logged on to comment or reply to a post.