Skip to Content

Tip: How To Get SAP GUI Scripting Profile Parameters with PowerShell and NCo

Often it is necessary to set the SAP GUI Scripting parameters with transaction code RZ11 in an SAP system. In this post I will present an example how to get and set this parameters via a PowerShell script and NCo.

In the first step the script gets the attributes from sapgui/user_script% from table TPFYPROPTY. Then it looks whether the attribute can be changed. If it is possible it gets via RFM PFL_GET_PARAMETER_INFO the user and the default value. Then it compares this values with the necessary standard and if they are different it changes the value.

If I use the RFM TH_CHANGE_PARAMETER via NCo, it delivers always the error NOT_IN_SAME_SYSTEM. So I programmed a wrapper Z_TH_CHANGE_PARAMETER which adds DESTINATION ‘NONE’ to the call.

#-Begin-----------------------------------------------------------------

#-Loads SAP dotNET Connector Libraries----------------------------------
Function Load-NCo {
  
  [String]$ScriptDir = $PSScriptRoot
  
  If ([Environment]::Is64BitProcess) {
    [String]$Path = $ScriptDir + "\x64\"
  } Else {
    [String]$Path = $ScriptDir + "\x86\"
  }
  
  [String]$File = $Path + "sapnco.dll"; Add-Type -Path $File
  $File = $Path + "sapnco_utils.dll"; Add-Type -Path $File
  
}

#-Delivers SAP Destination----------------------------------------------
Function Get-Destination {
  
  $cfgParams = New-Object SAP.Middleware.Connector.RfcConfigParameters
  $cfgParams.Add($cfgParams::Name, "TEST")
  $cfgParams.Add($cfgParams::AppServerHost, "ABAP702")
  $cfgParams.Add($cfgParams::SystemNumber, "00")
  $cfgParams.Add($cfgParams::Client, "001")
  $cfgParams.Add($cfgParams::User, "BCUSER")
  
  $SecPasswd = Read-Host -Prompt "Passwort" -AsSecureString
  $ptrPasswd = `
  [Runtime.InteropServices.Marshal]::SecureStringToBStr($SecPasswd)
  $Passwd = `
  [Runtime.InteropServices.Marshal]::PtrToStringBStr($ptrPasswd)
  $cfgParams.Add($cfgParams::Password, $Passwd)
  
  Return [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($cfgParams)
  
}

#-Shows SAP GUI Scripting Parameters from Transaction Code RZ11---------
Function Get-SAPGUIScriptingParams {
  
  $destination = Get-Destination
  
  $RfcReadTable = $destination.Repository.CreateFunction("RFC_READ_TABLE")
  $RfcParamInfo = $destination.Repository.CreateFunction("PFL_GET_PARAMETER_INFO")
  #$RfcParamChange = $destination.Repository.CreateFunction("TH_CHANGE_PARAMETER")
  $RfcParamChange = $destination.Repository.CreateFunction("Z_TH_CHANGE_PARAMETER")
  
  #-Get Parameter Attributes from SAP GUI Scripting---------------------
  $RfcReadTable.SetValue("QUERY_TABLE", "TPFYPROPTY")
  $RfcReadTable.SetValue("DELIMITER", ";")
  [SAP.Middleware.Connector.IRfcTable]$Fields = $RfcReadTable.GetTable("FIELDS")
  $Fields.Append()
  $Fields.SetValue("FIELDNAME", "PARANAME") #Profile parameter name
  $Fields.Append()
  $Fields.SetValue("FIELDNAME", "CHG") #Flag for changes
  $Fields.Append()
  $Fields.SetValue("FIELDNAME", "DESCR") #Short description
  $Fields.Append()
  $Fields.SetValue("FIELDNAME", "DYNAMIC") #Param. can be changed dynamically
  [SAP.Middleware.Connector.IRfcTable]$Options = $RfcReadTable.GetTable("OPTIONS")
  $Options.Append()
  $Options.SetValue("TEXT", "PARANAME LIKE 'sapgui/user_script%'")
  $RfcReadTable.Invoke($destination)
  
  [SAP.Middleware.Connector.IRfcTable]$Table = $RfcReadTable.GetTable("DATA")
  
  ForEach ($Line In $Table) {
    
    [System.Array]$Data = $Line.GetValue("WA").Split(";")
    
    If ($Data[1] -ne "X" -or $Data[3] -ne "X") {
      #Check if Param. can be changed
      Continue
    }
    
    $RfcParamInfo.SetValue("PARNAME", $Data[0])
    $RfcParamInfo.SetValue("PARTYPE", "I")
    $RfcParamInfo.Invoke($destination)
    [SAP.Middleware.Connector.IRfcStructure]$SubVal = `
      $RfcParamInfo.GetStructure("SUB_VAL")
    
    Write-Host $SubVal.GetValue("NAME") $SubVal.GetValue("USERVALUE") `
               $SubVal.GetValue("DEFVALUE")
    
    Switch ($SubVal.GetValue("NAME")) {
      "sapgui/user_scripting" {
        If ($SubVal.GetValue("USERVALUE") -ne "TRUE" -and `
          $SubVal.GetValue("DEFVALUE") -ne "TRUE") {
          $RfcParamChange.SetValue("PARAMETER_NAME", "sapgui/user_scripting")
          $RfcParamChange.SetValue("PARAMETER_VALUE", "TRUE")
          $RfcParamChange.Invoke($destination)
        }
      }
      {
        @("sapgui/user_scripting_disable_recording",
          "sapgui/user_scripting_force_notification",
          "sapgui/user_scripting_per_user",
          "sapgui/user_scripting_set_readonly") -contains $_
      }
      {
        If ($SubVal.GetValue("USERVALUE") -ne "FALSE" -and `
          $SubVal.GetValue("DEFVALUE") -ne "FALSE") {
          $RfcParamChange.SetValue("PARAMETER_NAME", $SubVal.GetValue("NAME"))
          $RfcParamChange.SetValue("PARAMETER_VALUE", "FALSE")
          $RfcParamChange.Invoke($destination)
        }
      }
    }
    
  }
  
}

#-Main Function---------------------------------------------------------
Function Main () {
  If ($PSVersionTable.PSVersion.Major -ge 5) {
    Load-NCo
    Get-SAPGUIScriptingParams
  }
}

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

#-Error Routine---------------------------------------------------------
Trap {
  [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > $Null
  [Void][System.Windows.Forms.MessageBox]::Show( `
    $_.Exception.GetType().FullName + `
    [System.Environment]::NewLine + `
    "Error at line " + $_.InvocationInfo.ScriptLineNumber + `
    " in " + $_.InvocationInfo.ScriptName + `
    [System.Environment]::NewLine + [System.Environment]::NewLine + `
    $_.Exception.Message, "An Error Occurred", 0)
  Exit
}

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

 

Here the result:

 

Here the RFM wrapper for TH_CHANGE_PARAMETER:

FUNCTION Z_TH_CHANGE_PARAMETER.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(PARAMETER_NAME) LIKE  TPFET-PARNAME
*"     VALUE(PARAMETER_VALUE) LIKE  TPFET-PVALUE
*"     VALUE(CHECK_PARAMETER) LIKE  SY-INDEX DEFAULT 1
*"  EXCEPTIONS
*"      NOT_AUTHORIZED
*"      NOT_IN_SAME_SYSTEM
*"      NOT_CHANGEABLE
*"      NOT_FOUND
*"      INVALID_VALUE
*"      SHMPRF_ERROR
*"      UNKNOWN_OPCODE
*"      LENGTH_EXCEEDED
*"      UNKNOWN
*"----------------------------------------------------------------------

  CALL FUNCTION 'TH_CHANGE_PARAMETER'
    DESTINATION 'NONE'
    EXPORTING
      PARAMETER_NAME     = PARAMETER_NAME
      PARAMETER_VALUE    = PARAMETER_VALUE
    EXCEPTIONS
      NOT_AUTHORIZED     = 1
      NOT_IN_SAME_SYSTEM = 2
      NOT_CHANGEABLE     = 3
      NOT_FOUND          = 4
      INVALID_VALUE      = 5
      SHMPRF_ERROR       = 6
      UNKNOWN_OPCODE     = 7
      LENGTH_EXCEEDED    = 8
      OTHERS             = 9.

  CASE sy-subrc.
    WHEN 1.
      RAISE NOT_AUTHORIZED.
    WHEN 2.
      RAISE NOT_IN_SAME_SYSTEM.
    WHEN 3.
      RAISE NOT_CHANGEABLE.
    WHEN 4.
      RAISE NOT_FOUND.
    WHEN 5.
      RAISE INVALID_VALUE.
    WHEN 6.
      RAISE SHMPRF_ERROR.
    WHEN 7.
      RAISE UNKNOWN_OPCODE.
    WHEN 8.
      RAISE LENGTH_EXCEEDED.
    WHEN 9.
      RAISE UNKNOWN.
  ENDCASE.

ENDFUNCTION.

 

On this way it is easy possible to check and to set the profile parameters for SAP GUI Scripting. Also this example is a good base to do the same with other profile parameters.

Be the first to leave a comment
You must be Logged on to comment or reply to a post.