Running PowerShell from a Python GUI
Data Goblins · May, MO · 1 mo ago
OTHRFull-time
Here’s the clean, semantic HTML fragment for the job posting (though this is actually a tutorial, so I’ve structured it accordingly):
About the Tutorial
This guide demonstrates how to create a Python GUI to run pbi-tools for decompiling Power BI (.pbix) files. The tutorial covers executing PowerShell commands from Python, building a simple GUI with Tkinter, and automating report modifications.
Use cases include programmatically adjusting column widths in tables/matrices and streamlining Power BI report development workflows.
Prerequisites
- Python 3.x installation (local environment, not Colab unless using local runtime)
- pbi-tools installed and added to system PATH
Key Steps
1. Running PowerShell from Python
Use Python's subprocess module to execute pbi-tools commands:
powershell = r'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' pbixpath = r'C:\path\to\report.pbix' outpath = r'C:\output\path\' subprocess.run(f'{powershell} pbi-tools extract {pbixpath} -extractFolder {outpath}')Capture output and check success status:
pbitools = subprocess.run(f'{powershell} pbi-tools extract {pbixpath}', capture_output=True) if pbitools.returncode == 0: print('Success 😁') else: print('Fail 😥')2. Creating a GUI with Tkinter
Build a simple interface for selecting input/output paths:
- Initialize a window with custom styling (size, color, title)
- Add text labels for instructions and path displays
- Implement file dialog buttons for .pbix selection and output path
- Add OK/Cancel buttons with conditional state management
3. Button Functionality
Define functions for each button:
- Input Browse: Open file dialog restricted to .pbix files, update path display
- Output Browse: Set output directory with automatic '/pbi-tools-output' suffix
- OK: Execute the PowerShell command with selected paths (enabled only after both paths are set)
- Cancel: Close the application
4. Widget Management
Dynamic UI updates:
- Hide browse buttons after selection using .place_forget()
- Update path labels with selected paths using .config()
- Enable OK button only when both paths are selected
Example Code Structure
from tkinter import * from tkinter import ttk, filedialog import subprocess class GUI: def __init__(self): self.root = Tk() self.root.title("Python pbi-tools") self.root.configure(bg='#f3f0ea', width=600, height=150) self.root.resizable(False, False) # Widget setup (labels, buttons) self.setup_ui() self.root.mainloop() def setup_ui(self): # Title label self.message = Label(self.root, text="Select a .pbix file to decompile", font=("Segoe UI", 14, 'bold'), bg='#f3f0ea') self.message.place(relx=0.14, rely=0.07) # Input path widgets self.LabelInputPath = Label(self.root, text="Input .pbix: ", bg='#f3f0ea') self.LabelInputPath.place(relx=0.117, rely=0.3) self.LabelSelectedFilePath = Label(self.root, text="Select a .pbix file", bg='#f3f0ea') self.LabelSelectedFilePath.place(relx=0.23, rely=0.3) self.button_input_browse = ttk.Button(self.root, text="Browse...", command=self.get_file_path) self.button_input_browse.place(relx=0.53, rely=0.315) # Output path widgets (similar structure) # ... [additional widgets] def get_file_path(self): file_path = filedialog.askopenfilename(filetypes=[("pbix files", "*.pbix")]) if file_path: self.LabelSelectedFilePath.config(text=file_path) self.button_input_browse.place_forget() self.check_ok_state() def check_ok_state(self): # Enable OK button when both paths are set if hasattr(self, 'file_path') and hasattr(self, 'output_path'): self.button_OK["state"] = NORMAL GUI()Security Note
When using subprocess, review the shell argument documentation for security considerations, especially when handling user-provided input.