Hello community,

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.

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