Add local Windows Server inventory collection and validation; include core package
This commit is contained in:
51
tools/validate_windows_host.py
Normal file
51
tools/validate_windows_host.py
Normal file
@@ -0,0 +1,51 @@
|
||||
"""Explicit real-host validation. Run manually on an authorized Windows Server only."""
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
import platform
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
from samsara.collectors.windows import collect_local_windows
|
||||
from samsara.analyzers.assessment import assess
|
||||
from samsara.reporting.export import export_html, export_json
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Perform local read-only Windows inventory and save validation evidence. No remote connections.')
|
||||
parser.add_argument('--output-dir', required=True, help='A NEW directory for sensitive host inventory and reports')
|
||||
args = parser.parse_args()
|
||||
if platform.system() != 'Windows':
|
||||
parser.error('Real-host validation requires an authorized local Windows Server execution host.')
|
||||
destination = Path(args.output_dir)
|
||||
if destination.exists():
|
||||
parser.error('Choose a new output directory; existing evidence will not be overwritten.')
|
||||
try:
|
||||
data = collect_local_windows(stage=lambda stage: print(stage, flush=True))
|
||||
# collect_local_windows already enforces the supported Server identity and schema.
|
||||
if data['synthetic']:
|
||||
raise ValueError('A synthetic result cannot be used for real-host validation.')
|
||||
destination.mkdir(parents=True, exist_ok=False)
|
||||
assessment = assess(data)
|
||||
export_json(destination / 'windows-assessment.json', data, assessment)
|
||||
export_html(destination / 'windows-assessment.html', data, assessment)
|
||||
summary = {
|
||||
'real_inventory_collected': True, 'synthetic': False, 'collected_at': data['collected_at'],
|
||||
'server_release': data['server']['os_version'], 'os_build': data['server']['os_build'],
|
||||
'product_type': data['server']['product_type'],
|
||||
'schema_validation': 'passed',
|
||||
'checks': {name: {'status': check['status'], 'error_codes': [e['code'] for e in check['errors']],
|
||||
'permission_limitations_reported': bool(check['permission_limitations'])}
|
||||
for name, check in data['checks'].items()},
|
||||
'counts': {name: len(rows) for name, rows in data['inventory'].items()},
|
||||
'review_required': True,
|
||||
}
|
||||
(destination / 'validation-summary.json').write_text(json.dumps(summary, indent=2), encoding='utf-8')
|
||||
print(json.dumps(summary, indent=2))
|
||||
print('Review partial/failed checks. Keep full inventory/reports private; validation-summary.json omits hostnames, accounts, IPs, paths and certificate identifiers.')
|
||||
except (OSError, ValueError, RuntimeError):
|
||||
parser.exit(1, 'Validation did not finish. Check supported local Server OS, 64-bit Python, script policy, read permissions and a new writable destination. Raw command diagnostics are excluded.\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user