Skip to Content

Hello community,

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.

Enjoy it.

Cheers
Stefan

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply