gooderp18绿色标准版
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

423 行
15KB

  1. ' Copyright (c) 2012-2020, EnterpriseDB Corporation. All rights reserved
  2. On Error Resume Next
  3. ' PostgreSQL server cluster init script for Windows
  4. ' Findings (ASHESH):
  5. ' - http://support.microsoft.com/kb/951978
  6. ' - http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/ca9c69e6-9b75-462f-b2e5-92198e584981
  7. Const ForReading = 1
  8. Const ForWriting = 2
  9. ' Check the command line
  10. If WScript.Arguments.Count <> 9 Then
  11. Wscript.Echo "Usage: initcluster.vbs <OSUsername> <SuperUsername> <Password> <PasswordDir> <Install dir> <Data dir> <Port> <Locale> <CheckACL>"
  12. Wscript.Quit 127
  13. End If
  14. strOSUsername = WScript.Arguments.Item(0)
  15. strUsername = WScript.Arguments.Item(1)
  16. strPassword = WScript.Arguments.Item(2)
  17. strPasswordDir = WScript.Arguments.Item(3)
  18. strInstallDir = WScript.Arguments.Item(4)
  19. strDataDir = WScript.Arguments.Item(5)
  20. lPort = CLng(WScript.Arguments.Item(6))
  21. strLocale = WScript.Arguments.Item(7)
  22. boolCheckAcl = WScript.Arguments.Item(8)
  23. ' Remove any trailing \'s from the data dir - they will confuse cacls
  24. If Right(strDataDir, 1) = "\" Then
  25. strDataDir = Left(strDataDir, Len(strDataDir)-1)
  26. End If
  27. Dim strInitdbPass
  28. iWarn = 0
  29. Dim objShell, objFso, objTempFolder, objWMI
  30. ' Get temporary filenames
  31. Set objShell = WScript.CreateObject("WScript.Shell")
  32. If objShell Is Nothing Then
  33. WScript.Echo "Couldn't create WScript.Shell object..."
  34. ElseIf IsObject(objShell) Then
  35. WScript.Echo "WScript.Shell Initialized..."
  36. Else
  37. WScript.Echo "WScript.Shell not initialized..."
  38. End If
  39. Set objFso = CreateObject("Scripting.FileSystemObject")
  40. If objFso Is Nothing Then
  41. WScript.Echo "Couldn't create Scripting.FileSystemObject object..."
  42. ElseIf IsObject(objFso) Then
  43. WScript.Echo "Scripting.FileSystemObject initialized..."
  44. Else
  45. WScript.Echo "Scripting.FileSystemObject not initialized..."
  46. End If
  47. Set objTempFolder = objFso.GetSpecialFolder(2)
  48. strBatchFile = Replace(objFso.GetTempName, ".tmp", ".bat")
  49. strOutputFile = objTempFolder.Path & "\" & objFso.GetTempName
  50. ' Change the current directory to the installation directory
  51. ' This is important, because initdb will drop Administrative
  52. ' permissions and may lose access to the current working directory
  53. objShell.CurrentDirectory = strInstallDir
  54. strProgramFiles = objShell.ExpandEnvironmentStrings("%PROGRAMFILES%")
  55. strSystemDrive = objShell.ExpandEnvironmentStrings("%SYSTEMDRIVE%")
  56. strWinDir = objShell.ExpandEnvironmentStrings("%WINDIR%")
  57. ' Is this Vista or above?
  58. Function IsVistaOrNewer()
  59. WScript.Echo "Called IsVistaOrNewer()..."
  60. Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
  61. If objWMI Is Nothing Then
  62. WScript.Echo " Couldn't create 'winmgmts:\\.\root\cimv2' object"
  63. IsVistaOrNewer=false
  64. ElseIf IsObject(objWMI) Then
  65. WScript.Echo " 'winmgmts' object initialized..."
  66. Else
  67. WScript.Echo " 'winmgmts' object not initialized..."
  68. End If
  69. Set colItems = objWMI.ExecQuery("Select * from Win32_OperatingSystem",,48)
  70. For Each objItem In colItems
  71. strVersion = Left(objItem.Version, 3)
  72. Next
  73. WScript.Echo " Version:" & strVersion
  74. If InStr(strVersion, ".") > 0 Then
  75. majorVersion = CInt(Left(strVersion, InStr(strVersion, ".") - 1))
  76. ElseIf InStr(strVersion, ",") > 0 Then
  77. majorVersion = CInt(Left(strVersion, InStr(strVersion, ",") - 1))
  78. Else
  79. majorVersion = CInt(strVersion)
  80. End If
  81. WScript.Echo " MajorVersion:" & majorVersion
  82. If majorVersion >= 6.0 Then
  83. IsVistaOrNewer = True
  84. Else
  85. IsVistaOrNewer = False
  86. End If
  87. End Function
  88. ' Execute a command
  89. Function DoCmd(strCmd)
  90. Dim objBatchFile
  91. Set objBatchFile = objTempFolder.CreateTextFile(strBatchFile, True)
  92. objBatchFile.WriteLine "@ECHO OFF"
  93. objBatchFile.WriteLine "CHCP " & objShell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\ACP")
  94. objBatchFile.WriteLine strCmd & " > """ & strOutputFile & """ 2>&1"
  95. objBatchFile.WriteLine "EXIT /B %ERRORLEVEL%"
  96. objBatchFile.Close
  97. WScript.Echo " Executing batch file '" & strBatchFile & "'..."
  98. DoCmd = objShell.Run(objTempFolder.Path & "\" & strBatchFile, 0, True)
  99. If objFso.FileExists(objTempFolder.Path & "\" & strBatchFile) = True Then
  100. objFso.DeleteFile objTempFolder.Path & "\" & strBatchFile, True
  101. Else
  102. WScript.Echo " Batch file '" & strBatchFile & "' does not exist..."
  103. End If
  104. If objFso.FileExists(strOutputFile) = True Then
  105. Dim objOutputFile
  106. Set objOutputFile = objFso.OpenTextFile(strOutputFile, ForReading)
  107. WScript.Echo " " & objOutputFile.ReadAll
  108. objOutputFile.Close
  109. objFso.DeleteFile strOutputFile, True
  110. Else
  111. WScript.Echo " Output file does not exists..."
  112. End If
  113. End Function
  114. Sub Die(msg)
  115. WScript.Echo "Called Die(" & msg & ")..."
  116. If objFso.FileExists(strInitdbPass) = True Then
  117. objFso.DeleteFile strInitdbPass, True
  118. End If
  119. WScript.Echo msg
  120. WScript.Quit 1
  121. End Sub
  122. Sub Warn(msg)
  123. WScript.Echo msg
  124. iWarn = 2
  125. End Sub
  126. Function ClearAcl(DirectoryPath)
  127. WScript.Echo "Called ClearAcl (" & DirectoryPath & ")..."
  128. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & DirectoryPath & """")
  129. WScript.Echo "Removing inherited ACLs on (" & DirectoryPath & ")"
  130. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & DirectoryPath & """ /inheritance:r")
  131. if iRet <> 0 Then
  132. WScript.Echo "Failed to remove inherited ACLs on (" & DirectoryPath & ")"
  133. End If
  134. End Function
  135. Function CreateDirectory(DirectoryPath)
  136. WScript.Echo "Called CreateDirectory(" & DirectoryPath & ")..."
  137. If objFso.FolderExists(DirectoryPath) Then Exit Function
  138. Call CreateDirectory(objFso.GetParentFolderName(DirectoryPath))
  139. objFso.CreateFolder(DirectoryPath)
  140. End Function
  141. ' Create a password file
  142. strInitdbPass = strPasswordDir & "\" & objFso.GetTempName
  143. Dim objInitdbPass
  144. Set objInitdbPass = objFso.OpenTextFile(strInitdbPass, ForWriting, True)
  145. WScript.Echo Err.description
  146. objInitdbPass.WriteLine(strPassword)
  147. objInitdbPass.Close
  148. ' Create the data directory
  149. If objFso.FolderExists(strDataDir) <> True Then
  150. CreateDirectory(strDataDir)
  151. If Err.number <> 0 Then
  152. Die "Failed to create the data directory (" & strDataDir & ")"
  153. End If
  154. End If
  155. ' Remove inherited ACEs
  156. ClearAcl(strDataDir)
  157. If Err.number <> 0 Then
  158. Die "Failed to reset the ACL (" & strDataDir & ")"
  159. End If
  160. Dim objNetwork
  161. Set objNetwork = CreateObject("WScript.Network")
  162. If objNetwork Is Nothing Then
  163. WScript.Echo "Couldn't create WScript.Network object"
  164. ElseIf IsObject(objNetwork) Then
  165. WScript.Echo "WScript.Network initialized..."
  166. Else
  167. WScript.Echo "WScript.Network not initialized..."
  168. End If
  169. Sub AclCheck(strThisDir, userName, index)
  170. WScript.Echo "Called AclCheck(" & strThisDir & ")"
  171. If strThisDir = strProgramFiles Then
  172. WScript.Echo "Skipping the ACL check on " & strThisDir
  173. iRet = 0
  174. ElseIf strThisDir = strSystemDrive Then
  175. WScript.Echo "Skipping the ACL check on " & strThisDir
  176. iRet = 0
  177. Else
  178. If IsVistaOrNewer() = True Then
  179. WScript.Echo "Executing icacls to ensure the " & userName & " account can read the path " & strThisDir
  180. If index <> 0 Then
  181. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strThisDir & """ /grant """ & userName & ":(NP)(RX)""")
  182. Else
  183. ' Drive letter must not be surronded by double-quotes and ends with slash (\)
  184. ' "icacls" fails on the drives with (NP) flag
  185. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strThisDir & """\ /grant """ & userName & ":(NP)(RX)""")
  186. End If
  187. Else
  188. WScript.Echo "Executing cacls to ensure the " & userName & " account can read the path " & strThisDir
  189. If index <> 0 Then
  190. iRet = DoCmd("echo y|cacls """ & strThisDir & """ /E /G """ & userName & """:R")
  191. Else
  192. iRet = DoCmd("echo y|cacls " & strThisDir & "\ /E /G """ & userName & """:R")
  193. End If
  194. End If
  195. End If
  196. if iRet <> 0 Then
  197. WScript.Echo "Failed to ensure the path " * strThisDir & " is readable"
  198. End If
  199. End Sub
  200. ' dirname of strDataDir'
  201. strParentOfDataDir = objFSO.GetParentFolderName(strDataDir)
  202. WScript.Echo "strParentOfDataDir" & strParentOfDataDir
  203. loggedInUser=objNetwork.UserDomain & "\" & objNetwork.Username
  204. WScript.Echo "logged in user" & loggedInUser
  205. If boolCheckAcl Then
  206. ' Loop up the directory path, and ensure we have read permissions
  207. ' on the entire path leading to the data directory
  208. arrDirs = Split(strParentOfDataDir, "\")
  209. nDirs = UBound(arrDirs)
  210. WScript.Echo "nDirs" & nDirs
  211. strThisDir = ""
  212. For d = 0 To nDirs
  213. strThisDir = strThisDir & arrDirs(d)
  214. Call AclCheck (strThisDir,loggedInUser,d)
  215. strThisDir = strThisDir & "\"
  216. Next
  217. WScript.Echo "Parent of Data ("& strParentOfDataDir &")"
  218. WScript.Echo "Install Dir ("& strInstallDir &")"
  219. End If
  220. Call AclCheck(strDataDir,loggedInUser,1)
  221. If boolCheckAcl Then
  222. If IsVistaOrNewer() = True Then
  223. WScript.Echo "Granting the " & loggedInUser & " permissions on " & strInstallDir
  224. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strInstallDir & """ /T /grant:r """ & loggedInUser & ":(OI)(CI)(RX)""")
  225. Else
  226. iRet = DoCmd("echo y|cacls """ & strInstallDir & """ /E /T /G """ & loggedInUser & """:F")
  227. End If
  228. if iRet <> 0 Then
  229. WScript.Echo "Failed to ensure the Install directory is accessible (" & strInstallDir & ")"
  230. End If
  231. End If
  232. ' Grant ACLs for specific users on data directory'
  233. If IsVistaOrNewer() = True Then
  234. WScript.Echo "Ensuring we can write to the data directory (using icacls) to " & loggedInUser & ":"
  235. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strDataDir & """ /T /grant:r """ & loggedInUser & ":(OI)(CI)F""")
  236. Else
  237. WScript.Echo "Ensuring we can write to the data directory (using cacls):"
  238. iRet = DoCmd("echo y|cacls """ & strDataDir & """ /E /T /G """ & loggedIUser & """:F")
  239. End If
  240. if iRet <> 0 Then
  241. WScript.Echo "Failed to ensure the data directory is accessible (" & strDataDir & ")"
  242. End If
  243. If IsVistaOrNewer() = True Then
  244. WScript.Echo "Granting full access to ("& strOSUsername & ") on (" & strDataDir & ")"
  245. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strDataDir & """ /grant """ & strOSUsername & ":(OI)(CI)F""")
  246. End If
  247. if iRet <> 0 Then
  248. WScript.Echo "Failed to grant access to ("& strOSUsername & ") on (" & strDataDir & ")"
  249. End If
  250. If IsVistaOrNewer() = True Then
  251. WScript.Echo "Granting full access to CREATOR OWNER on (" & strDataDir & ")"
  252. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strDataDir & """ /grant ""*S-1-3-0"":(OI)(CI)F")
  253. End If
  254. if iRet <> 0 Then
  255. WScript.Echo "Failed to grant access to CREATOR OWNER on (" & strDataDir & ")"
  256. End If
  257. If IsVistaOrNewer() = True Then
  258. WScript.Echo "Granting full access to SYSTEM on (" & strDataDir & ")"
  259. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strDataDir & """ /grant ""*S-1-5-18"":(OI)(CI)F")
  260. End If
  261. if iRet <> 0 Then
  262. WScript.Echo "Failed to grant access to SYSTEM on (" & strDataDir & ")"
  263. End If
  264. If IsVistaOrNewer() = True Then
  265. WScript.Echo "Granting full access to Administrators on (" & strDataDir & ")"
  266. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strDataDir & """ /grant ""*S-1-5-32-544"":(OI)(CI)F")
  267. End If
  268. if iRet <> 0 Then
  269. WScript.Echo "Failed to grant access to Administrators on (" & strDataDir & ")"
  270. End If
  271. ' Initialise the database cluster, and set the appropriate permissions/ownership
  272. if strLocale = "DEFAULT" Then
  273. iRet = DoCmd("""" & strInstallDir & "\bin\initdb.exe"" --pwfile """ & strInitdbPass & """ --encoding=UTF-8 -A md5 -U " & strUsername & " -D """ & strDataDir & """")
  274. Else
  275. iRet = DoCmd("""" & strInstallDir & "\bin\initdb.exe"" --pwfile """ & strInitdbPass & """ --locale=""" & strLocale & """ --encoding=UTF-8 -A md5 -U " & strUsername & " -D """ & strDataDir & """")
  276. End If
  277. if iRet <> 0 Then
  278. Die "Failed to initialise the database cluster with initdb"
  279. End If
  280. ' Delete the password file
  281. If objFso.FileExists(strInitdbPass) Then
  282. objFso.DeleteFile strInitdbPass, True
  283. End If
  284. ' Edit the config files
  285. ' Set the following in postgresql.conf:
  286. ' listen_addresses = '*'
  287. ' port = $PORT
  288. ' log_destination = 'stderr'
  289. ' logging_collector = on
  290. ' log_line_prefix = '%t '
  291. Dim objConfFil
  292. Set objConfFile = objFso.OpenTextFile(strDataDir & "\postgresql.conf", ForReading)
  293. If objConfFile Is Nothing Then
  294. WScript.Echo "Reading: objConfFile is nothing..."
  295. ElseIf IsObject(objConfFile) Then
  296. WScript.Echo "Reading: " & strDataDir & "\postgresql.conf exists..."
  297. Else
  298. WScript.Echo "Reading: " & strDataDir & "\postgresql.conf not exists..."
  299. End If
  300. strConfig = objConfFile.ReadAll
  301. objConfFile.Close
  302. strConfig = Replace(strConfig, "#listen_addresses = 'localhost'", "listen_addresses = '*'")
  303. strConfig = Replace(strConfig, "#port = 5432", "port = " & lPort)
  304. strConfig = Replace(strConfig, "#log_destination = 'stderr'", "log_destination = 'stderr'")
  305. strConfig = Replace(strConfig, "#logging_collector = off", "logging_collector = on")
  306. strConfig = Replace(strConfig, "#log_line_prefix = ''", "log_line_prefix = '%t '")
  307. Set objConfFile = objFso.OpenTextFile(strDataDir & "\postgresql.conf", ForWriting)
  308. If objConfFile Is Nothing Then
  309. WScript.Echo "Writing: objConfFile is nothing..."
  310. ElseIf IsObject(objConfFile) Then
  311. WScript.Echo "Writing: " & strDataDir & "\postgresql.conf exists..."
  312. Else
  313. WScript.Echo "Writing: " & strDataDir & "\postgresql.conf not exists..."
  314. End If
  315. objConfFile.WriteLine strConfig
  316. objConfFile.Close
  317. If boolCheckAcl Then
  318. ' Loop up the directory path, and ensure the service account has read permissions
  319. ' on the entire path leading to the data directory
  320. arrDirs = Split(strParentOfDataDir, "\")
  321. nDirs = UBound(arrDirs)
  322. strThisDir = ""
  323. For d = 0 To nDirs
  324. strThisDir = strThisDir & arrDirs(d)
  325. Call AclCheck(strThisDir,strOSUsername,d)
  326. strThisDir = strThisDir & "\"
  327. Next
  328. End If
  329. Call AclCheck(strDataDir,strOSUsername,1)
  330. If boolCheckAcl Then
  331. If IsVistaOrNewer() = True Then
  332. WScript.Echo "Granting " & strOSUsername & " permissions on " & strInstallDir
  333. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strInstallDir & """ /T /grant:r """ & strOSUsername & """:(OI)(CI)(RX)")
  334. Else
  335. iRet = DoCmd("echo y|cacls """ & strInstallDir & """ /E /T /G """ & strOSUsername & """:F")
  336. End If
  337. if iRet <> 0 Then
  338. WScript.Echo "Failed to ensure the Install directory is accessible (" & strInstallDir & ")"
  339. End If
  340. End If
  341. ' Create the <DATA_DIR>\log directory (if not exists)
  342. ' Create it before updating the permissions, so that it will also get affected
  343. If Not objFso.FolderExists(strDataDir & "\log") Then
  344. newfolder = objFso.CreateFolder (strDataDir & "\log")
  345. End If
  346. ' Secure the data directory
  347. If IsVistaOrNewer() = True Then
  348. WScript.Echo "Granting service account access to the data directory (using icacls) to " & strOSUsername & ":"
  349. iRet = DoCmd("""" & strWinDir & "\System32\icacls"" """ & strDataDir & """ /T /C /grant """ & strOSUsername & """:(OI)(CI)(F)")
  350. Else
  351. WScript.Echo "Granting service account access to the data directory (using cacls):"
  352. iRet = DoCmd("echo y|cacls """ & strDataDir & """ /E /T /C /G """ & strOSUsername & """:F")
  353. End If
  354. if iRet <> 0 Then
  355. Warn "Failed to grant service account access to the data directory (" & strDataDir & ")"
  356. End If
  357. WScript.Echo "initcluster.vbs ran to completion"
  358. WScript.Quit iWarn
上海开阖软件有限公司 沪ICP备12045867号-1