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 COM Connector (CCo). Here now an example script in PowerShell, which bases on CCo, how to detect all connected systems and programs to an SAP system. This script has its origin in a discussion with our system administrator. He wants to know which programs accesses to which SAP system. On this way it is possible to detect the programs, e.g. Eclipse. Now we can run this script via scheduler e.g. on high noon, save the data and analyze it. This script uses the RFC-enabled function module GWY_READ_CONNECTED_SYSTEMS.
#-Begin-----------------------------------------------------------------

#-Constants-----------------------------------------------------------
$RFC_OK = 0
$VarByRef = -1

#-Includes------------------------------------------------------------
."COM.ps1"

#-Function Read-ConSys------------------------------------------------
Function Read-ConSys([String] $ASHost, [String] $SysNr,
[String] $Client, [String] $User, [String] $PassWd) {

$SAP = $null
$SAP = Create-Object "COMNWRFC"
if ($SAP -eq $null) {
Break
}

$hRFC = Invoke-Method $SAP "RfcOpenConnection" @(
"ASHOST=" + $ASHost + ", SYSNR=" + $SysNr + ", CLIENT=" +
$Client + ", USER=" + $User + ", PASSWD=" + $PassWd)
if ($hRFC -eq 0) {
Free-Object $SAP
Remove-Variable SAP
Break
}

$hFuncDesc = Invoke-Method $SAP "RfcGetFunctionDesc" @(
$hRFC, "GWY_READ_CONNECTED_SYSTEMS")
if ($hFuncDesc -eq 0) {
$rc = Invoke-Method $SAP "RfcCloseConnection" $hRFC
Free-Object $SAP
Remove-Variable SAP
Break
}

$hFunc = Invoke-Method $SAP "RfcCreateFunction" $hFuncDesc
if ($hFunc -eq 0) {
$rc = Invoke-Method $SAP "RfcCloseConnection" $hRFC
Free-Object $SAP
Remove-Variable SAP
Break
}

$rc = Invoke-Method $SAP "RfcInvoke" @($hRFC, $hFunc)
if ($rc -ne $RFC_OK) {
$rc = Invoke-Method $SAP "RfcDestroyFunction" $hFunc
$rc = Invoke-Method $SAP "RfcCloseConnection" $hRFC
Free-Object $SAP
Remove-Variable SAP
Break
}

$rc = Invoke-Method $SAP "RfcGetTable" @(
$hFunc, "CONNECTED_SYSTEMS", $VarByRef)
if ($rc -ne $RFC_OK) {
$rc = Invoke-Method $SAP "RfcDestroyFunction" $hFunc
$rc = Invoke-Method $SAP "RfcCloseConnection" $hRFC
Free-Object $SAP
Remove-Variable SAP
Break
}

$hTable = Get-Property $SAP "lngByRef"
$rc = Invoke-Method $SAP "RfcGetRowCount" @(
$hTable, $VarByRef)
$RowCount = Get-Property $SAP "lngByRef"

$rc = Invoke-Method $SAP "RfcMoveToFirstRow" $hTable

for ($i = 1; $i -le $RowCount ; $i++) {

$Row = Invoke-Method $SAP "RfcGetCurrentRow" $hTable

$rc = Invoke-Method $SAP "RfcGetChars" @(
$Row, "LUNAME", $VarByRef, 128)
$charBuffer = Get-Property $SAP "strByRef"
$txt = $txt + $charBuffer.Trim()

$rc = Invoke-Method $SAP "RfcGetChars" @(
$Row, "TPNAME", $VarByRef, 128)
$charBuffer = Get-Property $SAP "strByRef"
$txt = $txt + " " + $charBuffer.Trim()

$rc = Invoke-Method $SAP "RfcGetChars" @(
$Row, "ADDR1", $VarByRef, 16)
$charBuffer = Get-Property $SAP "strByRef"
$txt = $txt + " " + $charBuffer.Trim() + "`r`n"

if ($i -lt $RowCount) {
$rc = Invoke-Method $SAP "RfcMoveToNextRow" $hTable
}

}

$rc = Invoke-Method $SAP "RfcDestroyFunction" $hFunc
$rc = Invoke-Method $SAP "RfcCloseConnection" $hRFC
Free-Object $SAP
Remove-Variable SAP
$txt
}

#-Function Main-------------------------------------------------------
Function Main {
$Res = Read-ConSys -ASHost "NSP" -SysNr "00" -Client "001" `
-User "RFC" -PassWd "secret"
Write-Host $Res
}

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

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

You get the name of the connected unit in the field LUNAME and the program name in the field TPNAME. The field ADDR1 delivers the IP address of the connected system.

I presented here and here the basics how to use NCo with Powershell, and now here the same script with NCo:
#-Begin-----------------------------------------------------------------

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

$ScriptDir = $PSScriptRoot

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

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

}

#-Function Get-Destination--------------------------------------------
Function Get-Destination([String] $Name, [String] $ASHost,
[String] $SysNr, [String] $Client, [String] $User,
[String] $PassWd) {

#-Connection parameters-------------------------------------------
$cfgParams = New-Object SAP.Middleware.Connector.RfcConfigParameters
$cfgParams.Add("NAME", $Name)
$cfgParams.Add("ASHOST", $ASHost)
$cfgParams.Add("SYSNR", $SysNr)
$cfgParams.Add("CLIENT", $Client)
$cfgParams.Add("USER", $User)
$cfgParams.Add("PASSWD", $PassWd)

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

}

#-Sub Read-ConSys-----------------------------------------------------
Function Read-ConSys([String] $Name, [String] $ASHost,
[String] $SysNr, [String] $Client, [String] $User,
[String] $PassWd) {

$destination = Get-Destination -Name $Name -ASHost $ASHost `
-SysNr $SysNr -Client $Client -User $User -PassWd $PassWd

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

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

[SAP.Middleware.Connector.IRfcTable]$ConSys =
$rfcFunction.GetTable("CONNECTED_SYSTEMS")

ForEach ($line In $ConSys) {
$strText = $strText + $line.GetValue("LUNAME") + " " + `
$line.GetValue("TPNAME") + " " + $line.GetValue("ADDR1") + `
"`r`n"
}

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

Return $strText

}

#-Sub Main------------------------------------------------------------
Function Main () {
If ($PSVersionTable.PSVersion.Major -ge 5) {
Load-NCo
$strText = Read-ConSys -Name "TEST" -ASHost "NSP" -SysNr "00" `
-Client "001" -User "RFC" -PassWd "secret"
Write-Host $strText
}
}

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

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

Here the same script in VBScript:
'-Begin-----------------------------------------------------------------

'-Directives----------------------------------------------------------
Option Explicit

'-Constants-----------------------------------------------------------
Const RFC_OK = 0

'-Function ReadConSys-------------------------------------------------
Function ReadConSys(ASHost, SysNr, Client, User, PassWd)

'-Variables-------------------------------------------------------
Dim SAP, hRFC, rc, hFuncDesc, hFunc, hTable, RowCount, i, Row
Dim charBuffer, strText

Set SAP = CreateObject("COMNWRFC")
If Not IsObject(SAP) Then
Exit Function
End If

hRFC = SAP.RfcOpenConnection("ASHOST=" & ASHost & ", SYSNR=" & SysNr & _
", CLIENT=" & Client & ", USER=" & User & ", PASSWD=" & PassWd)
If hRFC = 0 Then
Set SAP = Nothing
Exit Function
End If

hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "GWY_READ_CONNECTED_SYSTEMS")
If hFuncDesc = 0 Then
rc = SAP.RfcCloseConnection(hRFC)
Set SAP = Nothing
Exit Function
End If

hFunc = SAP.RfcCreateFunction(hFuncDesc)
If hFunc = 0 Then
rc = SAP.RfcCloseConnection(hRFC)
Set SAP = Nothing
Exit Function
End If

If SAP.RfcInvoke(hRFC, hFunc) = RFC_OK Then
If SAP.RfcGetTable(hFunc, "CONNECTED_SYSTEMS", hTable) = RFC_OK Then
rc = SAP.RfcGetRowCount(hTable, RowCount)
rc = SAP.RfcMoveToFirstRow(hTable)
For i = 1 To RowCount
Row = SAP.RfcGetCurrentRow(hTable)
rc = SAP.RfcGetChars(Row, "LUNAME", charBuffer, 128)
strText = strText & Trim(charBuffer) & " "
rc = SAP.RfcGetChars(Row, "TPNAME", charBuffer, 128)
strText = strText & Trim(charBuffer) & " "
rc = SAP.RfcGetChars(Row, "ADDR1", charBuffer, 16)
strText = strText & Trim(charBuffer) & vbCrLf
If i < RowCount Then
rc = SAP.RfcMoveToNextRow(hTable)
End If
Next
End If
End If

rc = SAP.RfcDestroyFunction(hFunc)
rc = SAP.RfcCloseConnection(hRFC)
Set SAP = Nothing

ReadConSys = strText

End Function

'-Sub Main------------------------------------------------------------
Sub Main()
MsgBox ReadConSys("NSP", "00", "001", "RFC", "secret")
End Sub

'-Main----------------------------------------------------------------
Main()

'-End-------------------------------------------------------------------

You can easily concatenate the systems you want and store the result in a text or csv file.