Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_schnell
Active Contributor
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 😎 {
$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 😎 {
$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.
4 Comments