Initial commit
This commit is contained in:
172
scripts/winrm/smart_executor.py
Executable file
172
scripts/winrm/smart_executor.py
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Smart Executor - Automatically choose between SSH and WinRM
|
||||
Based on script size and complexity
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from winrm import Session
|
||||
|
||||
|
||||
class SmartExecutor:
|
||||
def __init__(self, host=None, username=None, password=None):
|
||||
self.host = host or os.getenv('HOST', '192.168.88.108')
|
||||
self.username = username or os.getenv('USER_NAME', 'Admin')
|
||||
self.password = password or os.getenv('PASS', 'P@ssw0rd!')
|
||||
|
||||
def analyze_script(self, script_path):
|
||||
"""Analyze script to determine best execution method"""
|
||||
script_path = Path(script_path)
|
||||
|
||||
if not script_path.exists():
|
||||
return None
|
||||
|
||||
# Get script size
|
||||
size = script_path.stat().st_size
|
||||
|
||||
# Read content for analysis
|
||||
with open(script_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
lines = len(content.split('\n'))
|
||||
chars = len(content)
|
||||
|
||||
analysis = {
|
||||
'size_bytes': size,
|
||||
'lines': lines,
|
||||
'characters': chars,
|
||||
'has_file_operations': any(keyword in content.lower() for keyword in
|
||||
['out-file', 'copy-item', 'move-item', 'new-item', 'remove-item']),
|
||||
'has_long_commands': any(len(line) > 500 for line in content.split('\n')),
|
||||
'complexity_score': lines + (chars / 100) + (size / 1000)
|
||||
}
|
||||
|
||||
return analysis
|
||||
|
||||
def choose_method(self, script_path):
|
||||
"""Choose optimal execution method"""
|
||||
analysis = self.analyze_script(script_path)
|
||||
|
||||
if not analysis:
|
||||
return "error"
|
||||
|
||||
# Decision logic
|
||||
if analysis['size_bytes'] > 5000: # Large scripts
|
||||
return "ssh"
|
||||
elif analysis['lines'] > 100: # Many lines
|
||||
return "ssh"
|
||||
elif analysis['has_file_operations']: # File operations
|
||||
return "ssh"
|
||||
elif analysis['has_long_commands']: # Very long command lines
|
||||
return "ssh"
|
||||
elif analysis['complexity_score'] > 150: # Complex scripts
|
||||
return "ssh"
|
||||
else:
|
||||
return "winrm" # Simple, fast execution
|
||||
|
||||
def execute_via_ssh(self, script_path):
|
||||
"""Execute script using SSH method"""
|
||||
script_name = Path(script_path).stem
|
||||
ssh_script = f"{script_name}.sh"
|
||||
|
||||
if not Path(ssh_script).exists():
|
||||
print(f"❌ SSH wrapper {ssh_script} not found")
|
||||
return False
|
||||
|
||||
try:
|
||||
result = subprocess.run([f'./{ssh_script}'], capture_output=False, timeout=300)
|
||||
return result.returncode == 0
|
||||
except Exception as e:
|
||||
print(f"❌ SSH execution failed: {e}")
|
||||
return False
|
||||
|
||||
def execute_via_winrm(self, script_path):
|
||||
"""Execute script using WinRM method"""
|
||||
try:
|
||||
# Read and execute script content directly
|
||||
with open(script_path, 'r', encoding='utf-8') as f:
|
||||
script_content = f.read()
|
||||
|
||||
# Connect via WinRM
|
||||
session = Session(
|
||||
f'http://{self.host}:5985/wsman',
|
||||
auth=(self.username, self.password),
|
||||
transport='ntlm'
|
||||
)
|
||||
|
||||
# Execute PowerShell
|
||||
result = session.run_ps(script_content)
|
||||
|
||||
# Output results
|
||||
if result.std_out:
|
||||
output = result.std_out.decode('utf-8', errors='replace')
|
||||
for line in output.split('\n'):
|
||||
if line.strip():
|
||||
print(line)
|
||||
|
||||
if result.std_err:
|
||||
error = result.std_err.decode('utf-8', errors='replace')
|
||||
if error.strip():
|
||||
for line in error.split('\n'):
|
||||
if line.strip():
|
||||
print(f"ERROR: {line}")
|
||||
|
||||
return result.status_code == 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ WinRM execution failed: {e}")
|
||||
return False
|
||||
|
||||
def execute(self, script_path):
|
||||
"""Smart execute with automatic method selection"""
|
||||
script_path = Path(script_path)
|
||||
|
||||
print(f"🧠 Analyzing script: {script_path.name}")
|
||||
|
||||
analysis = self.analyze_script(script_path)
|
||||
method = self.choose_method(script_path)
|
||||
|
||||
print(f"📊 Script analysis:")
|
||||
print(f" Size: {analysis['size_bytes']} bytes")
|
||||
print(f" Lines: {analysis['lines']}")
|
||||
print(f" Complexity: {analysis['complexity_score']:.1f}")
|
||||
print(f" File operations: {analysis['has_file_operations']}")
|
||||
|
||||
print(f"⚡ Selected method: {method.upper()}")
|
||||
|
||||
if method == "ssh":
|
||||
print("🔗 Executing via SSH (for large/complex scripts)")
|
||||
return self.execute_via_ssh(script_path)
|
||||
elif method == "winrm":
|
||||
print("⚡ Executing via WinRM (for speed)")
|
||||
return self.execute_via_winrm(script_path)
|
||||
else:
|
||||
print("❌ Unable to determine execution method")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: python3 smart_executor.py <script.ps1>")
|
||||
sys.exit(1)
|
||||
|
||||
script_path = sys.argv[1]
|
||||
executor = SmartExecutor()
|
||||
|
||||
print("🎯 Smart PowerShell Executor")
|
||||
print("============================")
|
||||
|
||||
success = executor.execute(script_path)
|
||||
|
||||
if success:
|
||||
print(f"\n✅ Script execution completed successfully")
|
||||
else:
|
||||
print(f"\n❌ Script execution failed")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user