master
js 326 lines 12.8 KB
Raw
1 /*
2 Copyright 2019-2020 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 var promise = require('promise');
18
19 // We use the environment variable directly or the standard Windows path
20 var psPath = (process.env['SystemRoot'] ? process.env['SystemRoot'] : 'C:\\Windows') + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
21
22 function qfe()
23 {
24 try {
25 var tokens = require('win-wmi').query('ROOT\\CIMV2', 'SELECT * FROM Win32_QuickFixEngineering');
26 if (tokens[0]){
27 for (var index = 0; index < tokens.length; index++) {
28 for (var key in tokens[index]) {
29 if (key.startsWith('__')) delete tokens[index][key];
30 }
31 }
32 return (tokens);
33 } else {
34 return ([]);
35 }
36 } catch (ex) {
37 return ([]);
38 }
39 }
40 function av()
41 {
42 var result = [];
43 try {
44 var tokens = require('win-wmi-fixed').query('ROOT\\SecurityCenter2', 'SELECT * FROM AntiVirusProduct');
45 if (tokens.length == 0) { return ([]); }
46 // Process each antivirus product
47 for (var i = 0; i < tokens.length; ++i) {
48 var product = tokens[i];
49 var modifiedPath = product.pathToSignedProductExe || '';
50 // Expand environment variables (e.g., %ProgramFiles%)
51 var regex = /%([^%]+)%/g;
52 var match;
53 while ((match = regex.exec(product.pathToSignedProductExe)) !== null) {
54 var envVar = match[1];
55 var envValue = process.env[envVar] || '';
56 if (envValue) {
57 modifiedPath = modifiedPath.replace(match[0], envValue);
58 }
59 }
60 // Check if the executable exists (unless it's Windows Defender pseudo-path)
61 var flag = true;
62 if (modifiedPath !== 'windowsdefender://') {
63 try {
64 if (!require('fs').existsSync(modifiedPath)) {
65 flag = false;
66 }
67 } catch (ex) {
68 flag = false;
69 }
70 }
71 // Only include products with valid executables
72 if (flag) {
73 var status = {};
74 status.product = product.displayName || '';
75 status.updated = (parseInt(product.productState) & 0x10) == 0;
76 status.enabled = (parseInt(product.productState) & 0x1000) == 0x1000;
77 result.push(status);
78 }
79 }
80 return (result);
81 } catch (ex) {
82 return ([]);
83 }
84 }
85 function defrag(options)
86 {
87 var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
88 var path = '';
89
90 switch(require('os').arch())
91 {
92 case 'x64':
93 if (require('_GenericMarshal').PointerSize == 4)
94 {
95 // 32 Bit App on 64 Bit Windows
96 ret._rej('Cannot defrag volume on 64 bit Windows from 32 bit application');
97 return (ret);
98 }
99 else
100 {
101 // 64 Bit App
102 path = process.env['windir'] + '\\System32\\defrag.exe';
103 }
104 break;
105 case 'ia32':
106 // 32 Bit App on 32 Bit Windows
107 path = process.env['windir'] + '\\System32\\defrag.exe';
108 break;
109 default:
110 ret._rej(require('os').arch() + ' not supported');
111 return (ret);
112 break;
113 }
114
115 ret.child = require('child_process').execFile(process.env['windir'] + '\\System32\\defrag.exe', ['defrag', options.volume + ' /A']);
116 ret.child.promise = ret;
117 ret.child.promise.options = options;
118 ret.child.stdout.str = ''; ret.child.stdout.on('data', function (c) { this.str += c.toString(); });
119 ret.child.stderr.str = ''; ret.child.stderr.on('data', function (c) { this.str += c.toString(); });
120 ret.child.on('exit', function (code)
121 {
122 var lines = this.stdout.str.trim().split('\r\n');
123 var obj = { volume: this.promise.options.volume };
124 for (var i in lines)
125 {
126 var token = lines[i].split('=');
127 if(token.length == 2)
128 {
129 switch(token[0].trim().toLowerCase())
130 {
131 case 'volume size':
132 obj['size'] = token[1];
133 break;
134 case 'free space':
135 obj['free'] = token[1];
136 break;
137 case 'total fragmented space':
138 obj['fragmented'] = token[1];
139 break;
140 case 'largest free space size':
141 obj['largestFragment'] = token[1];
142 break;
143 }
144 }
145 }
146 this.promise._res(obj);
147 });
148 return (ret);
149 }
150 function regQuery(H, Path, Key)
151 {
152 try
153 {
154 return(require('win-registry').QueryKey(H, Path, Key));
155 }
156 catch(e)
157 {
158 return (null);
159 }
160 }
161 function pendingReboot()
162 {
163 var tmp = null;
164 var ret = null;
165 var HKEY = require('win-registry').HKEY;
166 if(regQuery(HKEY.LocalMachine, 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing', 'RebootPending') !=null)
167 {
168 ret = 'Component Based Servicing';
169 }
170 else if(regQuery(HKEY.LocalMachine, 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate', 'RebootRequired'))
171 {
172 ret = 'Windows Update';
173 }
174 else if ((tmp=regQuery(HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager', 'PendingFileRenameOperations'))!=null && tmp != 0 && tmp != '')
175 {
176 ret = 'File Rename';
177 }
178 else if (regQuery(HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName', 'ComputerName') != regQuery(HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName', 'ComputerName'))
179 {
180 ret = 'System Rename';
181 }
182 return (ret);
183 }
184
185 function installedApps() {
186 var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
187 var registry = require('win-registry');
188 var HKEY = registry.HKEY;
189 var results = [];
190 var registryPaths = [
191 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',
192 'SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'
193 ];
194 try {
195 for (var i in registryPaths) {
196 var path = registryPaths[i];
197 var keyInfo = registry.QueryKey(HKEY.LocalMachine, path);
198 if (!keyInfo || !keyInfo.subkeys) continue;
199 for (var j = 0; j < keyInfo.subkeys.length; j++) {
200 var subPath = path + '\\' + keyInfo.subkeys[j];
201 var name = regQuery(HKEY.LocalMachine, subPath, 'DisplayName');
202 if (name && name != '') {
203 results.push({
204 name: name,
205 version: regQuery(HKEY.LocalMachine, subPath, 'DisplayVersion') || '',
206 publisher: regQuery(HKEY.LocalMachine, subPath, 'Publisher') || '',
207 uninstall: regQuery(HKEY.LocalMachine, subPath, 'QuietUninstallString') || regQuery(HKEY.LocalMachine, subPath, 'UninstallString') || '',
208 location: regQuery(HKEY.LocalMachine, subPath, 'InstallLocation') || '',
209 date: regQuery(HKEY.LocalMachine, subPath, 'InstallDate') || ''
210 });
211 }
212 }
213 }
214 } catch (e) {
215 ret._rej(e);
216 return (ret);
217 }
218 ret._res(results);
219 return (ret);
220 }
221
222 function installedStoreApps() {
223 var ret = new promise(function (a, r) { this._resolve = a; this._reject = r; });
224
225 // Basierend auf deiner funktionierenden Version + Scope-Erkennung
226 var psCommand = [
227 "$ErrorActionPreference = 'SilentlyContinue'",
228 "$allUsersApps = @(Get-AppxPackage -AllUsers)",
229 "$allUsersPkgNames = @($allUsersApps | Select-Object -ExpandProperty PackageFullName)",
230 "$userOnlyApps = @(Get-AppxPackage | Where-Object { $allUsersPkgNames -notcontains $_.PackageFullName })",
231 "$provPkgs = @(Get-AppxProvisionedPackage -Online | Select-Object -ExpandProperty DisplayName)",
232 "$results = @()",
233 "foreach ($app in $allUsersApps) {",
234 " if ($app.Name -and $app.Name -notlike 'Microsoft.Windows.*' -and $app.Name -notlike 'windows.*' -and $app.Name -notlike '*_neutral_*') {",
235 " $scope = 'System'",
236 " if ($provPkgs -contains $app.Name) { $scope = 'System+Prov' }",
237 " $results += [PSCustomObject]@{ Name=$app.Name; Version=[string]$app.Version; PackageFullName=$app.PackageFullName; Publisher=$app.Publisher; Scope=$scope }",
238 " }",
239 "}",
240 "foreach ($app in $userOnlyApps) {",
241 " if ($app.Name -and $app.Name -notlike 'Microsoft.Windows.*' -and $app.Name -notlike 'windows.*' -and $app.Name -notlike '*_neutral_*') {",
242 " $scope = 'User'",
243 " if ($provPkgs -contains $app.Name) { $scope = 'User+Prov' }",
244 " $results += [PSCustomObject]@{ Name=$app.Name; Version=[string]$app.Version; PackageFullName=$app.PackageFullName; Publisher=$app.Publisher; Scope=$scope }",
245 " }",
246 "}",
247 "$results | Sort-Object Name -Unique | ConvertTo-Json -Compress"
248 ].join("; ");
249
250 try {
251 var psPath = (process.env['SystemRoot'] || 'C:\\Windows') + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
252
253 ret.child = require('child_process').execFile(
254 psPath,
255 ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', psCommand],
256 { timeout: 60000, maxBuffer: 10 * 1024 * 1024 }
257 );
258
259 ret.child.promise = ret;
260 ret.child.stdout.str = '';
261 ret.child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
262
263 ret.child.on('exit', function (code) {
264 try {
265 var output = this.stdout.str.trim();
266
267 if (output === '' || output === 'null' || output === '[]') {
268 this.promise._resolve([]);
269 return;
270 }
271
272 var data = JSON.parse(output);
273 if (!Array.isArray(data)) { data = [data]; }
274
275 var apps = data.map(function(app) {
276 return {
277 name: app.Name || '',
278 version: app.Version || '',
279 publisher: app.Publisher || '',
280 packageFullName: app.PackageFullName || '',
281 scope: app.Scope || '',
282 uninstall: 'Remove-AppxPackage -Package "' + (app.PackageFullName || '') + '" -AllUsers'
283 };
284 });
285
286 this.promise._resolve(apps);
287 } catch (e) {
288 this.promise._resolve([]);
289 }
290 });
291
292 ret.child.on('error', function (err) {
293 this.promise._resolve([]);
294 });
295 } catch (ex) {
296 ret._resolve([]);
297 }
298
299 return (ret);
300 }
301
302 function defender(){
303 try {
304 var tokens = require('win-wmi').query('ROOT\\Microsoft\\Windows\\Defender', 'SELECT * FROM MSFT_MpComputerStatus', ['RealTimeProtectionEnabled','IsTamperProtected','AntivirusSignatureVersion','AntivirusSignatureLastUpdated']);
305 if (tokens[0]){
306 var info = { RealTimeProtection: tokens[0].RealTimeProtectionEnabled, TamperProtected: tokens[0].IsTamperProtected };
307 if (tokens[0].AntivirusSignatureVersion) { info.AntivirusSignatureVersion = tokens[0].AntivirusSignatureVersion; }
308 if (tokens[0].AntivirusSignatureLastUpdated) { info.AntivirusSignatureLastUpdated = tokens[0].AntivirusSignatureLastUpdated; }
309 return (info);
310 } else {
311 return ({});
312 }
313 } catch (ex) {
314 return ({});
315 }
316 }
317
318 if (process.platform == 'win32')
319 {
320 module.exports = { qfe: qfe, av: av, defrag: defrag, pendingReboot: pendingReboot, installedApps: installedApps, installedStoreApps: installedStoreApps, defender: defender };
321 }
322 else
323 {
324 var not_supported = function () { throw (process.platform + ' not supported'); };
325 module.exports = { qfe: not_supported, av: not_supported, defrag: not_supported, pendingReboot: not_supported, installedApps: not_supported, installedStoreApps: not_supported, defender: not_supported };
326 }