-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSapConnection.vbs
More file actions
139 lines (114 loc) · 4.4 KB
/
Copy pathSapConnection.vbs
File metadata and controls
139 lines (114 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
Option Explicit
'--------------------------------------------------------------------------------
' ScriptName : SapConnection.vbs
' Creator : Sungman Han
' Creation Date : 2019-05-28
' Description : Attaches to a running SAP GUI, opens a connection and logs on.
'
' Usage : set SAP_PASSWORD=<password>
' cscript //nologo SapConnection.vbs <connectionString> <language> <user>
'
' Why the password comes from the environment:
' command line arguments are visible to every process on the box
' (Task Manager details column, WMI Win32_Process, Sysmon event 1),
' so a password must never be passed as an argument.
'
' Exit codes : 0 ok | 1 bad arguments | 2 SAP GUI unavailable
'
' Requires : SAP GUI for Windows with scripting enabled on both the client
' (Options > Accessibility & Scripting) and the server
' (profile parameter sapgui/user_scripting = TRUE).
'--------------------------------------------------------------------------------
Const MAX_ATTEMPTS = 60
Const POLL_INTERVAL_MS = 500
Dim vConnectionString, vLanguage, vUserName, vPassword
Dim vApplication, vConnection, vSession
If WScript.Arguments.Count < 3 Then
WScript.StdErr.WriteLine "Usage: cscript //nologo SapConnection.vbs <connectionString> <language> <user>"
WScript.StdErr.WriteLine " the password is read from the SAP_PASSWORD environment variable"
WScript.Quit 1
End If
vConnectionString = WScript.Arguments.Item(0)
vLanguage = WScript.Arguments.Item(1)
vUserName = WScript.Arguments.Item(2)
vPassword = CreateObject("WScript.Shell").Environment("Process").Item("SAP_PASSWORD")
If vPassword = "" Then
WScript.StdErr.WriteLine "SAP_PASSWORD is not set."
WScript.Quit 1
End If
Set vApplication = WaitForScriptingEngine()
Set vConnection = WaitForConnection(vApplication, vConnectionString)
Set vSession = WaitForSession(vConnection)
If IsObject(WScript) Then
WScript.ConnectObject vSession, "on"
WScript.ConnectObject vApplication, "on"
End If
'--------------------------------------------------------------------------------
' Logon screen
'--------------------------------------------------------------------------------
vSession.findById("wnd[0]").maximize
vSession.findById("wnd[0]/usr/txtRSYST-LANGU").Text = vLanguage
vSession.findById("wnd[0]/usr/txtRSYST-BNAME").Text = vUserName
vSession.findById("wnd[0]/usr/pwdRSYST-BCODE").Text = vPassword
vSession.findById("wnd[0]").sendVKey 0
vPassword = ""
WScript.Quit 0
'--------------------------------------------------------------------------------
' Function List
'--------------------------------------------------------------------------------
' The three waits below share one shape: the SAP GUI object model is populated
' asynchronously, so every step is polled instead of assumed present. Each gives
' up after MAX_ATTEMPTS rather than spinning forever.
Function WaitForScriptingEngine()
Dim vGuiAuto, vEngine, vAttempt
Set vEngine = Nothing
For vAttempt = 1 To MAX_ATTEMPTS
On Error Resume Next
Set vGuiAuto = GetObject("SAPGUI")
If Err.Number = 0 Then Set vEngine = vGuiAuto.GetScriptingEngine
Err.Clear
On Error GoTo 0
If Not vEngine Is Nothing Then
Set WaitForScriptingEngine = vEngine
Exit Function
End If
WScript.Sleep POLL_INTERVAL_MS
Next
Fail 2, "SAP GUI scripting engine not available. Is SAP Logon running and scripting enabled?"
End Function
Function WaitForConnection(vApp, vConnStr)
Dim vConn, vAttempt
Set vConn = Nothing
For vAttempt = 1 To MAX_ATTEMPTS
On Error Resume Next
Set vConn = vApp.OpenConnectionByConnectionString(vConnStr, True)
Err.Clear
On Error GoTo 0
If Not vConn Is Nothing Then
Set WaitForConnection = vConn
Exit Function
End If
WScript.Sleep POLL_INTERVAL_MS
Next
Fail 2, "Could not open a connection for: " & vConnStr
End Function
Function WaitForSession(vConn)
Dim vSess, vAttempt
Set vSess = Nothing
For vAttempt = 1 To MAX_ATTEMPTS
On Error Resume Next
Set vSess = vConn.Children(0)
Err.Clear
On Error GoTo 0
If Not vSess Is Nothing Then
Set WaitForSession = vSess
Exit Function
End If
WScript.Sleep POLL_INTERVAL_MS
Next
Fail 2, "The connection never produced a session."
End Function
Sub Fail(vCode, vMessage)
WScript.StdErr.WriteLine vMessage
WScript.Quit vCode
End Sub