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.