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
At the beginning of this year I presented here, here and here different possibilities to use SAPs .NET Connector (NCo) in the context of the scripting language PowerShell. Now with new experience and knowledge I can say that the use of this combination is very profitably. You can try different programming situations fast, without a special IDE. Also you can use it to automate a lot of things, e.g. to download and compare data (customizing on different systems). The PowerShell ISE (Integrated Script Environment) with the integrated debugger offers a good range of functions, e.g. like syntax highlighting and code completion. All in all I can recommend PowerShell unlimited. As a further outlook for the future, a combination of SAP GUI Scripting, NCo and PowerShell seems very interesting. We will see...

Here now two more examples. The first shows how to ping an SAP system via RFC_PING and the build-in ping from NCo. The second shows how to get system via the function module RFC_SYSTEM_INFO. The code is commented and I think easy to understand. It shows, in conjunction with the links above, all variants of parameters.

1st example - Ping
#-Begin-----------------------------------------------------------------

<#
.Synopsis
Calls PING of an SAP system.
.Description
Calls the function module RFC_PING and the build-in function
Ping of the .NET connector.
#>

#-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 {

#-Connection 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 Execute-Ping----------------------------------------------------
Function Execute-Ping () {

$destination = Get-Destination

#-Metadata--------------------------------------------------------
[SAP.Middleware.Connector.IRfcFunction]$rfcFunction =
$destination.Repository.CreateFunction("RFC_PING")

#-Variant 1: Call function module---------------------------------
Try {
$rfcFunction.Invoke($destination)
Write-Host "Ping successful"
}
Catch {
Write-Host "Exception" $_.Exception.Message "occured"
}

#-Variant 2: Call build-in function-------------------------------
Try {
$destination.Ping()
Write-Host "Ping successful"
}
Catch {
Write-Host "Exception" $_.Exception.Message "occured"
}

}

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

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

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

2nd example - RFC_SYSTEM_INFO
#-Begin-----------------------------------------------------------------

<#
.Synopsis
Calls RFC_SYSTEM_INFO of an SAP system.
.Description
Calls the function module RFC_SYSTEM_INFO and writes the result
on the screen.
#>

#-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 {

#-Connection 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 Get-SystemInfo--------------------------------------------------
Function Get-SystemInfo () {

$destination = Get-Destination

#-Metadata--------------------------------------------------------
[SAP.Middleware.Connector.IRfcFunction]$rfcFunction =
$destination.Repository.CreateFunction("RFC_SYSTEM_INFO")

#-Call function module--------------------------------------------
Try {
$rfcFunction.Invoke($destination)

[SAP.Middleware.Connector.IRfcStructure]$Export =
$rfcFunction.GetStructure("RFCSI_EXPORT")

#-Get information---------------------------------------------
Write-Host $Export.GetValue("RFCHOST")
Write-Host $Export.GetValue("RFCSYSID")
Write-Host $Export.GetValue("RFCDBHOST")
Write-Host $Export.GetValue("RFCDBSYS")

}
Catch {
Write-Host "Exception" $_.Exception.Message "occured"
}

}

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

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

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

3rd example - RFC_READ_TABLE
#-Begin-----------------------------------------------------------------

<#
.Synopsis
Calls RFC_READ_TABLE of an SAP system.
.Description
Calls the function module RFC_READ_TABLE and writes the result
on the screen.
#>

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

$ScriptDir = $PSScriptRoot

If ([Environment]::Is64BitProcess) {
$Path = $ScriptDir + "\x64\"
}
Else {
$Path = $ScriptDir + "\x86\"
}

$File = $Path + "sapnco.dll"; Add-Type -Path $File
$File = $Path + "sapnco_utils.dll"; Add-Type -Path $File

}

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

#-Connection 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 Read-Table------------------------------------------------------
Function Read-Table ([String]$TableName) {

$destination = Get-Destination

#-Metadata--------------------------------------------------------
$rfcFunction = `
$destination.Repository.CreateFunction("RFC_READ_TABLE")

#-Call function module--------------------------------------------
Try {
$rfcFunction.SetValue("QUERY_TABLE", $TableName)
$rfcFunction.SetValue("DELIMITER", ";")

$rfcFunction.Invoke($destination)

[SAP.Middleware.Connector.IRfcTable]$Table = `
$rfcFunction.GetTable("DATA")

ForEach ($Line In $Table) {
Write-Host $Line.GetValue("WA")
}

}
Catch {
Write-Host "Exception occured:`r`n" $_.Exception.Message
}


}

#-Sub Main------------------------------------------------------------
Function Main () {
If ($PSVersionTable.PSVersion.Major -ge 5) {
Load-NCo
Read-Table "USR01"
}
}

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

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

4th example - RFC_READ_TABLE with JSON result
#-Begin-----------------------------------------------------------------

<#
.Synopsis
Calls RFC_READ_TABLE of an SAP system.
.Description
Calls the function module RFC_READ_TABLE and writes the result
in JSON on the screen.
#>

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

$ScriptDir = $PSScriptRoot

If ([Environment]::Is64BitProcess) {
$Path = $ScriptDir + "\x64\"
}
Else {
$Path = $ScriptDir + "\x86\"
}

$File = $Path + "sapnco.dll"; Add-Type -Path $File
$File = $Path + "sapnco_utils.dll"; Add-Type -Path $File

}

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

#-Connection 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 Read-Table------------------------------------------------------
Function Read-Table-JSON ([String]$TableName, [Int]$RowCount) {

$destination = Get-Destination

#-Metadata--------------------------------------------------------
$rfcFunction = `
$destination.Repository.CreateFunction("RFC_READ_TABLE")

#-Call function module--------------------------------------------
Try {
$rfcFunction.SetValue("QUERY_TABLE", $TableName)
$rfcFunction.SetValue("DELIMITER", "~")
$rfcFunction.SetValue("ROWCOUNT", $RowCount)

$rfcFunction.Invoke($destination)

$Header = New-Object System.Collections.ArrayList

#-Get field names for the CSV header--------------------------
[SAP.Middleware.Connector.IRfcTable]$Fields = `
$rfcFunction.GetTable("FIELDS")
ForEach ($Field In $Fields) {
[Void]$Header.Add($Field.GetValue("FIELDNAME"))
}

#-Get table data line by line for CSV-------------------------
[SAP.Middleware.Connector.IRfcTable]$Table = `
$rfcFunction.GetTable("DATA")
ForEach ($Line In $Table) {
$CSV = $CSV + $Line.GetValue("WA") + "`r`n"
}

#-Convert CSV to JSON-----------------------------------------
$JSON = $CSV | ConvertFrom-Csv -Delimiter "~" `
-Header $Header | ConvertTo-Json

Return $JSON

}
Catch {
Write-Host "Exception occured:`r`n" $_.Exception.Message
}


}

#-Sub Main------------------------------------------------------------
Function Main () {
If ($PSVersionTable.PSVersion.Major -ge 5) {
Load-NCo
Write-Host(Read-Table-JSON "SFLIGHT" 0)
}
}

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

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

If you like you can find the same functionality here, with SAP NetWeaver RFC SDK and FreeBASIC, to compare it.
1 Comment