diff --git a/scripts/export_bitlocker.ps1 b/scripts/export_bitlocker.ps1 new file mode 100644 index 00000000..8848166c --- /dev/null +++ b/scripts/export_bitlocker.ps1 @@ -0,0 +1,79 @@ +# Export Bitlocker info + +# Init +$REPORT = "" +$SKIPPED_PROPERTIES = @( + "CapacityGB", + "MountPoint", + "KeyProtector" +) + +# Functions +function Convert-BytesToString ($bytes) { + If ($bytes -gt 1PB) { + return ("{0:0.#} PB" -f ($bytes / 1PB) ) + } ElseIf ($bytes -gt 1TB) { + return ("{0:0.#} TB" -f ($bytes / 1TB) ) + } ElseIf ($bytes -gt 1GB) { + return ("{0:0.#} GB" -f ($bytes / 1GB) ) + } ElseIf ($bytes -gt 1MB) { + return ("{0:0.#} MB" -f ($bytes / 1MB) ) + } ElseIf ($bytes -gt 1KB) { + return ("{0:0.#} KB" -f ($bytes / 1KB) ) + } Else { + return ("{0} B" -f $bytes) + } +} + + +# Build report +$system_drive = $env:SystemDrive +if ($system_drive -eq "X:") { + # Assuming we're running in WinPE + $system_drive = "C:" +} +Get-BitlockerVolume -MountPoint $system_drive | ForEach-Object { + $bitlocker_volume = $_ + $REPORT += ("`n`nDrive {0}`n---`n" -f $bitlocker_volume.MountPoint) + + # Size info + $volume = Get-Volume -DriveLetter $bitlocker_volume.MountPoint[0] + $total = Convert-BytesToString ($volume.Size) + $used = Convert-BytesToString ($volume.Size - $volume.SizeRemaining) + if ($volume.Size -gt 0) { + $REPORT += ("Size: {0} ({1} used)`n" -f $total, $used) + } else { + $REPORT += "Size: Unknown`n" + } + + # Volume info + $bitlocker_volume | + Get-Member -MemberType Property | + Where-Object {! $SKIPPED_PROPERTIES.Contains($_.Name)} | + ForEach-Object { + $name = $_.Name + if ($bitlocker_volume.$name -ne $null) { + $REPORT += ("{0}: {1}`n" -f $name, $bitlocker_volume.$name) + } + } + + # Key info + $bitlocker_volume.KeyProtector | + ForEach-Object { + $key = $_ + $REPORT += "Key Slot:`n" + $key | + Get-Member -MemberType Property | + ForEach-Object { + $name = $_.Name + if ($key.$name -ne $null -and $key.$name -ne "") { + $REPORT += ("... {0}: {1}`n" -f $name, $key.$name) + } + } + } +} + +# Show report +Write-Host $REPORT.Trim() + +# vim: sts=2 sw=2 ts=2 diff --git a/scripts/wk/os/win.py b/scripts/wk/os/win.py index a16bcbd7..2da33c05 100644 --- a/scripts/wk/os/win.py +++ b/scripts/wk/os/win.py @@ -28,7 +28,7 @@ from wk.cfg.windows_builds import ( ) from wk.exe import get_json_from_command, run_program, wait_for_procs from wk.kit.tools import find_kit_dir -from wk.osticket import osTicket, pad_with_dots +from wk.osticket import osTicket from wk.std import ( GenericError, GenericWarning, @@ -217,50 +217,34 @@ def defender_is_disabled(): def export_bitlocker_info() -> None: """Get Bitlocker info and save to either the base directory of the kit or osTicket.""" - commands = [ - ['manage-bde', '-status', SYSTEMDRIVE], - ['manage-bde', '-protectors', '-get', SYSTEMDRIVE], - ] + script_path = find_kit_dir('Scripts').joinpath('export_bitlocker.ps1') + cmd = ['PowerShell', '-ExecutionPolicy', 'Bypass', '-File', script_path] file_name = '' output = [] - output_raw = [] - output_str = '' - # WinPE check + # Include OS info if os.environ.get('SYSTEMDRIVE', 'C:').upper() == 'X:': + # Assuming this is true output.append('[Check run under Win10XPE]') + else: + output.append(get_os_name()) + output.append('') - # Get info - for cmd in commands: - proc = run_program(cmd, check=False) - if proc.stdout: - output_raw.extend(proc.stdout.splitlines()[3:]) - for line in output_raw: - if line.startswith(' ') and ':' in line: - parts = line.split(':') - if len(parts) < 2: - # Not a key/value pair - output.append(f'.. {line}') - continue - key = parts.pop(0) - key = f'.. {key.strip()+":":<22}' - key = pad_with_dots(key, pad_right=True) - value = ' '.join(parts) - value = value.strip() - output.append(f'{key} {value}') - else: - output.append(line) - output_str = '\n'.join(output) + # Get Bitlocker info + proc = run_program(cmd, check=False) + if proc.returncode or not proc.stdout.strip(): + output.append('Error: Failed to export Bitlocker info\n') + output.extend(proc.stdout.splitlines()) # Show info - print('\n'.join(output_raw), '\n\n') + print('\n'.join(output), '\n\n') # Save to osTicket ost = osTicket() ost.init() ost.select_ticket() if not ost.disabled: - ost.post_response(output_str) + ost.post_response('\n'.join(output)) result = 'OK' if ost.disabled or ost.errors: result = 'Unknown' @@ -278,7 +262,7 @@ def export_bitlocker_info() -> None: file_name = ui.input_text(prompt_msg='Enter filename: ', allow_empty=False) file_path = pathlib.Path(f'../../../Bitlocker_{file_name}.txt').resolve() with open(file_path, 'a', encoding='utf-8') as _f: - _f.write('\n'.join(output_raw)) + _f.write('\n'.join(output)) # Done ui.pause('\nPress Enter to exit...')