sync: auto-sync from Mikes-MacBook-Air.local at 2026-07-08 06:49:28
Author: Mike Swanson Machine: Mikes-MacBook-Air.local Timestamp: 2026-07-08 06:49:28
This commit is contained in:
161
.glaztech-update-sites.py
Executable file
161
.glaztech-update-sites.py
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Glaztech ScreenConnect Site Tag Update
|
||||
Maps machines to sites based on subnet, then batch-updates CustomProperty2 (Site)
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# Subnet to Site mapping
|
||||
SUBNET_MAP = {
|
||||
'192.168.0': 'TUC',
|
||||
'192.168.1': 'SAN',
|
||||
'192.168.2': 'PHX',
|
||||
'192.168.4': 'DEN',
|
||||
'192.168.5': 'BOI',
|
||||
'192.168.6': 'SLC',
|
||||
'192.168.7': 'BRL',
|
||||
'192.168.8': 'INV',
|
||||
'192.168.9': 'SHV',
|
||||
'192.168.10': 'ABQ',
|
||||
'192.168.12': 'SLC',
|
||||
}
|
||||
|
||||
def get_site_for_ip(ip):
|
||||
"""Determine site code from IP address"""
|
||||
if not ip:
|
||||
return None
|
||||
|
||||
# VPN clients (10.x.x.x)
|
||||
if ip.startswith('10.'):
|
||||
return 'REMOTE'
|
||||
|
||||
# Standard subnets
|
||||
subnet = '.'.join(ip.split('.')[:3])
|
||||
return SUBNET_MAP.get(subnet)
|
||||
|
||||
def main():
|
||||
preview_only = '--preview' in sys.argv
|
||||
|
||||
# Load sessions
|
||||
with open('/Users/azcomputerguru/ClaudeTools/.glaztech-sessions.json') as f:
|
||||
sessions = json.load(f)
|
||||
|
||||
updates = []
|
||||
no_change = []
|
||||
no_mapping = []
|
||||
|
||||
for session in sessions:
|
||||
session_id = session.get('SessionID')
|
||||
name = session.get('Name', 'Unknown')
|
||||
ip = session.get('GuestInfo', {}).get('PrivateNetworkAddress', '')
|
||||
current_site = session.get('CustomProperties', {}).get('CustomProperty2', '')
|
||||
company = session.get('CustomProperties', {}).get('CustomProperty1', '')
|
||||
tag = session.get('CustomProperties', {}).get('CustomProperty3', '')
|
||||
|
||||
new_site = get_site_for_ip(ip)
|
||||
|
||||
if not new_site:
|
||||
no_mapping.append({'name': name, 'ip': ip, 'session_id': session_id})
|
||||
continue
|
||||
|
||||
if current_site == new_site:
|
||||
no_change.append({'name': name, 'ip': ip, 'site': new_site})
|
||||
else:
|
||||
updates.append({
|
||||
'session_id': session_id,
|
||||
'name': name,
|
||||
'ip': ip,
|
||||
'current_site': current_site,
|
||||
'new_site': new_site,
|
||||
'company': company,
|
||||
'tag': tag
|
||||
})
|
||||
|
||||
# Report
|
||||
print(f'=== Glaztech Site Tag Update ===')
|
||||
print(f'Total machines: {len(sessions)}')
|
||||
print(f'Need update: {len(updates)}')
|
||||
print(f'Already correct: {len(no_change)}')
|
||||
print(f'No mapping: {len(no_mapping)}')
|
||||
|
||||
if no_mapping:
|
||||
print('\n[WARNING] Machines with no subnet mapping:')
|
||||
for m in no_mapping:
|
||||
print(f' {m["name"]:30s} {m["ip"]:15s} SessionID: {m["session_id"]}')
|
||||
|
||||
if not updates:
|
||||
print('\n[OK] All machines already have correct Site tags.')
|
||||
return 0
|
||||
|
||||
print(f'\n=== Changes Preview ===')
|
||||
print(f'{"Name":30s} {"IP":15s} {"Current":10s} -> {"New":10s}')
|
||||
print('-' * 70)
|
||||
for u in updates[:20]: # Show first 20
|
||||
print(f'{u["name"]:30s} {u["ip"]:15s} {u["current_site"]:10s} -> {u["new_site"]:10s}')
|
||||
if len(updates) > 20:
|
||||
print(f'... and {len(updates) - 20} more')
|
||||
|
||||
if preview_only:
|
||||
print('\n[PREVIEW MODE] Use --execute to apply changes')
|
||||
return 0
|
||||
|
||||
if '--execute' not in sys.argv:
|
||||
print('\n[INFO] Dry run complete. Add --execute to apply changes.')
|
||||
return 0
|
||||
|
||||
# Execute updates
|
||||
print(f'\n=== Executing {len(updates)} updates ===')
|
||||
success_count = 0
|
||||
fail_count = 0
|
||||
|
||||
for i, u in enumerate(updates, 1):
|
||||
# Build custom properties array: [Company, Site, Tag, ...]
|
||||
# Keep existing Company/Tag, update Site only
|
||||
props = [
|
||||
u['company'] or 'Glaz-Tech Industries',
|
||||
u['new_site'],
|
||||
u['tag'] or '',
|
||||
'', '', '', '', '' # CP4-CP8 empty
|
||||
]
|
||||
props_json = json.dumps(props)
|
||||
|
||||
cmd = [
|
||||
'bash',
|
||||
'/Users/azcomputerguru/ClaudeTools/.claude/scripts/py.sh',
|
||||
'/Users/azcomputerguru/.claude/skills/screenconnect/scripts/sc.py',
|
||||
'set-properties',
|
||||
'--session', u['session_id'],
|
||||
'--props-json', props_json,
|
||||
'--confirm'
|
||||
]
|
||||
|
||||
env = {
|
||||
'CLAUDETOOLS_ROOT': '/Users/azcomputerguru/ClaudeTools',
|
||||
'PATH': os.environ.get('PATH', '/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin'),
|
||||
'HOME': os.environ.get('HOME', '/Users/azcomputerguru'),
|
||||
'SCREENCONNECT_API_SECRET': os.environ.get('SCREENCONNECT_API_SECRET', '')
|
||||
}
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, env=env, capture_output=True, text=True, timeout=30)
|
||||
if result.returncode == 0:
|
||||
print(f'[{i}/{len(updates)}] OK: {u["name"]} -> {u["new_site"]}')
|
||||
success_count += 1
|
||||
else:
|
||||
print(f'[{i}/{len(updates)}] FAIL: {u["name"]} - {result.stderr.strip()}')
|
||||
fail_count += 1
|
||||
except Exception as e:
|
||||
print(f'[{i}/{len(updates)}] ERROR: {u["name"]} - {e}')
|
||||
fail_count += 1
|
||||
|
||||
print(f'\n=== Summary ===')
|
||||
print(f'Success: {success_count}')
|
||||
print(f'Failed: {fail_count}')
|
||||
|
||||
return 0 if fail_count == 0 else 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user