winscripts.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package fsdriver
  15. const WinScriptChangePassword = `
  16. $username = $args[0]
  17. $passwd = $args[1]
  18. $loghash = $args[2]
  19. $logpath = $args[3]
  20. Function ChangePassword($u, $p) {
  21. $admin = [adsi]("WinNT://./$($u), user")
  22. $succ = 0
  23. $tried = 0
  24. $max_tries = 10
  25. while (($succ -eq 0) -and ($tried -lt $max_tries)) {
  26. Try {
  27. $admin.psbase.invoke("SetPassword", $p)
  28. $admin.psbase.CommitChanges()
  29. $succ = 1
  30. } Catch {
  31. Start-Sleep -s 1
  32. }
  33. $tried = $tried + 1
  34. }
  35. }
  36. if ($username -and $passwd) {
  37. if ($logpath) {
  38. "starting $loghash" | Out-File $logpath -Append -Encoding Default
  39. ChangePassword $username $passwd 2>&1 | Out-File $logpath -Append -Encoding Default
  40. } else {
  41. ChangePassword $username $passwd 2>&1 | Out-Null
  42. }
  43. }
  44. `
  45. const WinScriptMountDisk = `
  46. var MTW_GLOBAL_FSO = new ActiveXObject('Scripting.FileSystemObject');
  47. var MTW_SCRIPT_PATH = mtw_gen_script_path();
  48. var MTW_DEBUG_STREAM = null;
  49. function mtw_create_shell() {
  50. return new ActiveXObject('WScript.Shell');
  51. }
  52. function mtw_gen_script_path() {
  53. var fso = MTW_GLOBAL_FSO;
  54. var folder = fso.GetSpecialFolder(2); // TemporaryFolder
  55. var folder_path = folder + '';
  56. var script_name = [];
  57. if (!/[\\\/]$/.test(folder_path)) {
  58. folder_path += '\\';
  59. }
  60. for (var i = 0; i < 5; i++) {
  61. script_name.push(mtw_gen_random_str(6));
  62. }
  63. return folder_path + script_name.join('-');
  64. }
  65. function mtw_gen_random_str(length) {
  66. var offset, result = [];
  67. var charcode_base = 'A'.charCodeAt(0);
  68. for (var i = 0; i < length; i++) {
  69. offset = Math.floor(Math.random() * 26);
  70. result.push(String.fromCharCode(charcode_base + offset));
  71. }
  72. return result.join('');
  73. }
  74. function mtw_prepare_debug(file_path) {
  75. var fso = new ActiveXObject('Scripting.FileSystemObject');
  76. var stream = fso.OpenTextFile(file_path, 8, true); // 8: ForAppending
  77. stream.WriteLine('');
  78. stream.WriteLine('================ ' + new Date() + ' ================');
  79. stream.WriteLine('');
  80. MTW_DEBUG_STREAM = stream;
  81. }
  82. function mtw_append_debug(cmd_lines, result_lines) {
  83. var i, len, stream = MTW_DEBUG_STREAM;
  84. if (!stream) return;
  85. stream.WriteLine('');
  86. stream.WriteLine('---------- script:');
  87. for (i = 0, len = cmd_lines.length; i < len; i++) {
  88. stream.WriteLine(cmd_lines[i]);
  89. }
  90. stream.WriteLine('---------- result:');
  91. for (i = 0, len = result_lines.length; i < len; i++) {
  92. stream.WriteLine(result_lines[i]);
  93. }
  94. }
  95. function mtw_execute_diskpart(cmd_lines) {
  96. var result_lines = [];
  97. var fso = MTW_GLOBAL_FSO;
  98. var stream, shell, exec_cmd;
  99. cmd_lines.push('exit');
  100. stream = fso.CreateTextFile(MTW_SCRIPT_PATH, true);
  101. for (var i = 0, len = cmd_lines.length; i < len; i++) {
  102. stream.WriteLine(cmd_lines[i]);
  103. }
  104. stream.close();
  105. shell = mtw_create_shell();
  106. exec_cmd = shell.Exec('diskpart /s ' + MTW_SCRIPT_PATH);
  107. while (exec_cmd.Status == 0) {
  108. WScript.Sleep(100);
  109. }
  110. stream = exec_cmd.StdOut;
  111. while (!stream.AtEndOfStream) {
  112. result_lines.push(stream.ReadLine());
  113. }
  114. fso.DeleteFile(MTW_SCRIPT_PATH);
  115. mtw_append_debug(cmd_lines, result_lines);
  116. return result_lines;
  117. }
  118. function mtw_get_disk_list() {
  119. var result_lines, line, match, disk_no;
  120. var disk_list = [];
  121. result_lines = mtw_execute_diskpart(['list disk']);
  122. for (var i = 0, len = result_lines.length; i < len; i++) {
  123. line = result_lines[i];
  124. /*
  125. Disk ### Status Size Free Dyn Gpt
  126. -------- ------------- ------- ------- --- ---
  127. Disk 0 Online 20 GB 0 B
  128. Disk 1 Offline 10 GB 0 B
  129. */
  130. match = line.match(/\s([1-9])\s\D+\s[1-9]\d*\s+[GMK]B\s+\d+\s+[GMK]?B/);
  131. if (match) {
  132. disk_no = match[1];
  133. disk_list.push({
  134. 'disk_no': disk_no,
  135. 'partition_list': mtw_get_partition_list(disk_no)
  136. });
  137. }
  138. }
  139. return disk_list;
  140. }
  141. function mtw_get_partition_list(disk_no) {
  142. var result_lines, line, match, partition_no;
  143. var partition_list = [];
  144. result_lines = mtw_execute_diskpart([
  145. 'select disk=' + disk_no,
  146. 'list partition'
  147. ]);
  148. for (var i = 0, len = result_lines.length; i < len; i++) {
  149. line = result_lines[i];
  150. /*
  151. Partition ### Type Size Offset
  152. ------------- ---------------- ------- -------
  153. Partition 1 Primary 9 GB 1024 KB
  154. */
  155. match = line.match(/\s(\d)\s\D+\s[1-9]\d*\s+[GMK]B\s+\d+\s+[GMK]?B/);
  156. if (match) {
  157. partition_no = match[1];
  158. partition_list.push({
  159. 'partition_no': partition_no,
  160. 'partition_type': mtw_get_partition_type(disk_no, partition_no)
  161. });
  162. }
  163. }
  164. return partition_list;
  165. }
  166. var MTW_PARTITION_TYPE_NODATA = 'nodata';
  167. var MTW_PARTITION_TYPE_INVALID = 'invalid';
  168. function mtw_get_partition_type(disk_no, partition_no) {
  169. var result_lines, line, match;
  170. var possible_type_list = [];
  171. result_lines = mtw_execute_diskpart([
  172. 'select disk=' + disk_no,
  173. 'select partition=' + partition_no,
  174. 'detail partition'
  175. ]);
  176. for (var i = 0, len = result_lines.length; i < len; i++) {
  177. line = result_lines[i];
  178. /*
  179. Partition 1
  180. Type : 06
  181. Hidden: No
  182. Active: No
  183. Offset in Bytes: 1048576
  184. Volume ### Ltr Label Fs Type Size Status Info
  185. ---------- --- ----------- ----- ---------- ------- --------- --------
  186. * Volume 3 RAW Partition 9 GB Healthy
  187. */
  188. match = line.match(/:\s*([0-9a-f]{2})\b/i);
  189. if (match) {
  190. possible_type_list.push(match[1]);
  191. }
  192. }
  193. switch (possible_type_list.length) {
  194. case 0:
  195. return MTW_PARTITION_TYPE_NODATA;
  196. case 1:
  197. return possible_type_list[0];
  198. default:
  199. break;
  200. }
  201. return MTW_PARTITION_TYPE_INVALID;
  202. }
  203. function mtw_get_volume_list(disk_no) {
  204. var result_lines, line, match;
  205. var sep_line_exist = false;
  206. var volume_list = [];
  207. result_lines = mtw_execute_diskpart([
  208. 'select disk=' + disk_no,
  209. 'detail disk'
  210. ]);
  211. for (var i = 0, len = result_lines.length; i < len; i++) {
  212. line = result_lines[i];
  213. /*
  214. Red Hat VirtIO SCSI Disk Device
  215. Disk ID: 0004B605
  216. Type : SCSI
  217. Status : Online
  218. Path : 0
  219. Target : 0
  220. LUN ID : 0
  221. Location Path : PCIROOT(0)#PCI(0600)#SCSI(P00T00L00)
  222. Current Read-only State : No
  223. Read-only : No
  224. Boot Disk : No
  225. Pagefile Disk : No
  226. Hibernation File Disk : No
  227. Crashdump Disk : No
  228. Clustered Disk : No
  229. Volume ### Ltr Label Fs Type Size Status Info
  230. ---------- --- ----------- ----- ---------- ------- --------- --------
  231. Volume 3 RAW Partition 9 GB Healthy
  232. */
  233. if (!sep_line_exist) {
  234. match = line.match(/-+\s+-+\s+-+\s+-+/);
  235. if (match) {
  236. sep_line_exist = true;
  237. }
  238. } else {
  239. match = line.match(/\s(\d)\s.+\s\d+\s+[GMK]?B/);
  240. if (match) {
  241. volume_list.push({'volume_no': match[1]});
  242. }
  243. }
  244. }
  245. return volume_list;
  246. }
  247. function mtw_assign_volume_letter(volume_no_set, letter_offset) {
  248. var result_lines, line, match, i, len;
  249. var volume_no, letter, charcode, charcode_max, letter_set;
  250. var volume_map = {}, volume_shift_list = [], cmd_lines = [];
  251. result_lines = mtw_execute_diskpart(['list volume']);
  252. for (i = 0, len = result_lines.length; i < len; i++) {
  253. line = result_lines[i];
  254. /*
  255. Volume ### Ltr Label Fs Type Size Status Info
  256. ---------- --- ----------- ----- ---------- ------- --------- --------
  257. Volume 0 D CD-ROM 0 B No Media
  258. Volume 1 ???? NTFS Partition 100 MB Healthy System
  259. Volume 2 C NTFS Partition 19 GB Healthy Boot
  260. Volume 3 RAW Partition 9 GB Healthy
  261. */
  262. match = line.match(/\s(\d)\s+([D-Z])\s.+\d+\s+[GMK]?B/i);
  263. if (match) {
  264. volume_no = match[1];
  265. letter = match[2].toUpperCase();
  266. if (volume_map.hasOwnProperty(letter)) {
  267. return false;
  268. }
  269. volume_map[letter] = volume_no;
  270. }
  271. }
  272. charcode = 'D'.charCodeAt(0);
  273. charcode += letter_offset;
  274. letter_set = String.fromCharCode(charcode);
  275. if (volume_map.hasOwnProperty(letter_set) && volume_map[letter_set] == volume_no_set) {
  276. return true;
  277. }
  278. charcode_max = 'Z'.charCodeAt(0);
  279. while (true) {
  280. letter = String.fromCharCode(charcode);
  281. if (!volume_map.hasOwnProperty(letter)) {
  282. break;
  283. }
  284. if (charcode >= charcode_max) {
  285. return false;
  286. }
  287. volume_shift_list.push({
  288. 'volume_no': volume_map[letter],
  289. 'charcode_next': charcode + 1
  290. });
  291. charcode++;
  292. }
  293. if (volume_shift_list.length > 0) {
  294. volume_shift_list.sort(function(a, b) {
  295. return b.charcode_next - a.charcode_next;
  296. });
  297. for (i = 0, len = volume_shift_list.length; i < len; i++) {
  298. volume_no = volume_shift_list[i].volume_no;
  299. charcode = volume_shift_list[i].charcode_next;
  300. cmd_lines.push(
  301. 'select volume=' + volume_no,
  302. 'assign letter=' + String.fromCharCode(charcode),
  303. 'select partition 1',
  304. 'format fs ntfs quick'
  305. );
  306. }
  307. }
  308. cmd_lines.push(
  309. 'select volume=' + volume_no_set,
  310. 'assign letter=' + letter_set,
  311. 'select partition 1',
  312. 'format fs ntfs quick'
  313. );
  314. mtw_execute_diskpart(cmd_lines);
  315. return true;
  316. }
  317. function mtw_wait_loop(total_ms, step_ms, callback) {
  318. while (true) {
  319. if (callback()) {
  320. break;
  321. }
  322. if (total_ms < step_ms) {
  323. break;
  324. }
  325. total_ms -= step_ms;
  326. WScript.Sleep(step_ms);
  327. }
  328. }
  329. function mtw_get_disk_list_wait() {
  330. var disk_list_ret = [];
  331. /* http://support.microsoft.com/kb/870912 */
  332. mtw_wait_loop(5000, 500, function() {
  333. var i, j, disk_list, disk, partition;
  334. disk_list = mtw_get_disk_list();
  335. for (i = 0; i < disk_list.length; i++) {
  336. disk = disk_list[i];
  337. for (j = 0; j < disk.partition_list.length; j++) {
  338. partition = disk.partition_list[j];
  339. if (partition.partition_type == MTW_PARTITION_TYPE_NODATA) {
  340. return false;
  341. }
  342. }
  343. }
  344. disk_list_ret = disk_list;
  345. return true;
  346. });
  347. return disk_list_ret;
  348. }
  349. function mtw_get_volume_list_wait(disk_no) {
  350. var volume_list_ret = [];
  351. mtw_wait_loop(5000, 500, function() {
  352. var volume_list = mtw_get_volume_list(disk_no);
  353. if (volume_list.length > 0) {
  354. volume_list_ret = volume_list;
  355. return true;
  356. }
  357. return false;
  358. });
  359. return volume_list_ret;
  360. }
  361. function mtw_mount_disk() {
  362. var disk_list, disk_list_mounted, disk, partition, volume_list;
  363. var do_mount, do_create, do_delete;
  364. var cmd_lines, letter_offset = 0;
  365. disk_list = mtw_get_disk_list_wait();
  366. disk_list_mounted = [];
  367. for (var i = 0, len = disk_list.length; i < len; i++) {
  368. disk = disk_list[i];
  369. partition = null;
  370. do_mount = do_create = do_delete = false;
  371. if (disk.partition_list.length == 0) {
  372. do_mount = true;
  373. do_create = true;
  374. } else if (disk.partition_list.length == 1) {
  375. partition = disk.partition_list[0];
  376. switch (partition.partition_type) {
  377. case '06': // DOS 3.31+ 16-bit FAT (over 32M)
  378. case '07': // Windows NT NTFS
  379. do_mount = true;
  380. break;
  381. case '83': // Linux native partition
  382. do_mount = true;
  383. do_delete = true;
  384. do_create = true;
  385. break;
  386. default:
  387. break;
  388. }
  389. }
  390. if (!do_mount) {
  391. continue;
  392. }
  393. cmd_lines = [
  394. 'select disk=' + disk.disk_no,
  395. 'online disk',
  396. 'attributes disk clear readonly'
  397. ];
  398. mtw_execute_diskpart(cmd_lines);
  399. if (do_create) {
  400. cmd_lines = ['select disk=' + disk.disk_no];
  401. if (partition && do_delete) {
  402. cmd_lines.push(
  403. 'select partition=' + partition.partition_no,
  404. 'delete partition'
  405. );
  406. }
  407. cmd_lines.push('create partition primary');
  408. mtw_execute_diskpart(cmd_lines);
  409. }
  410. disk_list_mounted.push(disk);
  411. }
  412. for (i = 0, len = disk_list_mounted.length; i < len; i++) {
  413. disk = disk_list_mounted[i];
  414. if (i == 0) {
  415. volume_list = mtw_get_volume_list_wait(disk.disk_no);
  416. } else {
  417. volume_list = mtw_get_volume_list(disk.disk_no);
  418. }
  419. if (volume_list.length == 1) {
  420. mtw_assign_volume_letter(volume_list[0].volume_no, letter_offset);
  421. letter_offset += 1;
  422. }
  423. }
  424. }
  425. function mtw_extend_c() {
  426. cmd_lines = [
  427. 'select volume c',
  428. 'extend',
  429. 'extend filesystem',
  430. ];
  431. mtw_execute_diskpart(cmd_lines);
  432. mtw_append_debug(["extend c"], ["success"]);
  433. }
  434. function mtw_main() {
  435. var exec_helper, args = WScript.Arguments, debug_path = '';
  436. for (var i = 0, len = args.length; i < len; i++) {
  437. if (args(i) == '--debug') {
  438. if (i < len) {
  439. i += 1;
  440. debug_path = args(i);
  441. }
  442. }
  443. }
  444. if (debug_path) {
  445. mtw_prepare_debug(debug_path);
  446. }
  447. /* http://support.microsoft.com/kb/937252 */
  448. exec_helper = mtw_create_shell().Exec('diskpart');
  449. try {
  450. mtw_extend_c();
  451. } catch (e) {
  452. mtw_append_debug(["extend c"], ["failed"]);
  453. }
  454. try {
  455. mtw_mount_disk();
  456. } catch (e) {
  457. // nothing
  458. }
  459. exec_helper.StdIn.WriteLine('exit');
  460. while (exec_helper.Status == 0) {
  461. WScript.Sleep(100);
  462. }
  463. }
  464. mtw_main();
  465. `
  466. const winTelegrafSetupPowerShellScript = `
  467. $telegraf = $args[0]
  468. $telegraf_conf = $args[1]
  469. & $telegraf --service install --config $telegraf_conf
  470. net start telegraf
  471. `