|
1 | | -<# |
| 1 | +<# |
2 | 2 | .SYNOPSIS |
3 | | - PowerShell Script for Broadcasting Logon Messages via GPO. |
| 3 | + Post-logon script to display a standard message via an HTA file. |
4 | 4 |
|
5 | 5 | .DESCRIPTION |
6 | | - This script displays customizable warning messages to users upon login via Group Policy, |
7 | | - enabling broad communication in managed environments and enhancing organizational messaging. |
| 6 | + - Executes the .HTA using mshta.exe so it does not depend on the system's file handler. |
| 7 | + - Writes execution logs to C:\Scripts-LOGS (one log file per script). |
| 8 | + - Designed to run as a User Logon Script via Group Policy. |
| 9 | + - Runs mshta in a hidden window to avoid flashing a console for users. |
8 | 10 |
|
9 | 11 | .AUTHOR |
10 | | - Luiz Hamilton Silva - @brazilianscriptguy |
| 12 | + Luiz Hamilton Silva - @brazilianscriptguy (adapted & generalized) |
11 | 13 |
|
12 | 14 | .VERSION |
13 | | - Last Updated: October 22, 2024 |
| 15 | + Last Updated: 2025-10-02 |
14 | 16 | #> |
15 | 17 |
|
16 | | -# Enhanced error handling |
17 | | -$ErrorActionPreference = "SilentlyContinue" |
| 18 | +param ( |
| 19 | + [string]$messagePath = "\\forest-logonserver\NETLOGON\broadcast-logonmessage\Broadcast-UserLogonMessageViaGPO.hta" |
| 20 | +) |
18 | 21 |
|
19 | | -# Define the log path for recording execution details |
20 | | -$logDir = 'C:\Logs-TEMP' |
21 | | -$logFileName = "BroadcastUserLogonMessage.log" |
22 | | -$logPath = Join-Path $logDir $logFileName |
| 22 | +# Fail quietly by default (caller environment controlled) |
| 23 | +$ErrorActionPreference = "SilentlyContinue" |
23 | 24 |
|
24 | | -# Ensure the log directory exists |
25 | | -if (-not (Test-Path $logDir)) { |
26 | | - $null = New-Item -Path $logDir -ItemType Directory -ErrorAction SilentlyContinue |
27 | | - if (-not (Test-Path $logDir)) { |
28 | | - Write-Error "Failed to create log directory at $logDir. Logging will not be possible." |
29 | | - return |
30 | | - } |
| 25 | +# --- Hide the console window --- |
| 26 | +Add-Type @" |
| 27 | +using System; |
| 28 | +using System.Runtime.InteropServices; |
| 29 | +public class Win32 { |
| 30 | + [DllImport("kernel32.dll")] public static extern IntPtr GetConsoleWindow(); |
| 31 | + [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); |
31 | 32 | } |
| 33 | +"@ |
| 34 | +try { |
| 35 | + $consolePtr = [Win32]::GetConsoleWindow() |
| 36 | + # 0 = SW_HIDE |
| 37 | + [Win32]::ShowWindow($consolePtr, 0) | Out-Null |
| 38 | +} catch { |
| 39 | + # If hiding fails, continue but log the condition below (if logging is available) |
| 40 | +} |
| 41 | +# --------------------------------- |
| 42 | + |
| 43 | +# Prepare logging |
| 44 | +$scriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name) |
| 45 | +$logDir = "C:\Scripts-LOGS" |
| 46 | +$logFileName = "${scriptName}.log" |
| 47 | +$logPath = Join-Path $logDir $logFileName |
32 | 48 |
|
33 | | -# Enhanced logging function |
34 | 49 | function Log-Message { |
35 | 50 | param ( |
36 | | - [Parameter(Mandatory = $true)] |
37 | | - [string]$Message, |
38 | | - [Parameter(Mandatory = $false)] |
39 | | - [string]$MessageType = "INFO" |
| 51 | + [Parameter(Mandatory = $true)][string]$Message, |
| 52 | + [string]$Severity = "INFO" |
40 | 53 | ) |
41 | | - $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" |
42 | | - $logEntry = "[$timestamp] [$MessageType] $Message" |
43 | 54 | try { |
44 | | - Add-Content -Path $logPath -Value $logEntry -ErrorAction Stop |
| 55 | + if (-not (Test-Path $logDir)) { |
| 56 | + New-Item -Path $logDir -ItemType Directory -Force | Out-Null |
| 57 | + } |
| 58 | + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" |
| 59 | + $entry = "[$timestamp] [$Severity] $Message" |
| 60 | + Add-Content -Path $logPath -Value $entry -ErrorAction Stop |
45 | 61 | } catch { |
46 | | - Write-Error "Failed to write to log: $_" |
| 62 | + # If logging fails, we cannot do much in a hidden logon script; swallow to avoid blocking logon |
47 | 63 | } |
48 | 64 | } |
49 | 65 |
|
50 | | -# Function to display the post-logon message |
51 | | -function Display-LogonMessage { |
52 | | - param ( |
53 | | - [string]$messageFilePath |
54 | | - ) |
| 66 | +# Start |
| 67 | +Log-Message "Script started. Target HTA: $messagePath" |
55 | 68 |
|
| 69 | +# Validate the HTA path and run it via mshta.exe |
| 70 | +if (Test-Path $messagePath -PathType Leaf) { |
| 71 | + Log-Message "HTA file found at: $messagePath" |
56 | 72 | try { |
57 | | - # Check if the logon message file exists |
58 | | - if (Test-Path $messageFilePath -PathType Leaf) { |
59 | | - Log-Message "Message file found at: $messageFilePath. Executing the script." |
60 | | - |
61 | | - # Create a shell object to run the Windows Script Host |
62 | | - $shell = New-Object -ComObject WScript.Shell |
63 | | - |
64 | | - # Execute the message file in a hidden window |
65 | | - $exitCode = $shell.Run($messageFilePath, 0, $true) |
66 | | - |
67 | | - # Log the success or failure of the execution |
68 | | - if ($exitCode -eq 0) { |
69 | | - Log-Message "Post-logon message executed successfully." |
70 | | - } else { |
71 | | - Log-Message "Post-logon message execution failed with exit code: $exitCode" -MessageType "ERROR" |
72 | | - } |
| 73 | + $mshta = Join-Path $env:windir "System32\mshta.exe" |
| 74 | + if (-not (Test-Path $mshta)) { |
| 75 | + Log-Message "mshta.exe not found at expected location: $mshta" "ERROR" |
73 | 76 | } else { |
74 | | - Log-Message "Post-logon message file not found at: $messageFilePath" -MessageType "ERROR" |
| 77 | + # Use Start-Process to launch mshta.exe with the HTA file; run hidden |
| 78 | + $args = "`"$messagePath`"" |
| 79 | + Start-Process -FilePath $mshta -ArgumentList $args -WindowStyle Hidden -NoNewWindow |
| 80 | + Log-Message "mshta.exe launched (hidden) for: $messagePath" |
75 | 81 | } |
76 | 82 | } catch { |
77 | | - Log-Message "An error occurred while attempting to execute the post-logon message: $_" -MessageType "ERROR" |
| 83 | + Log-Message "Error launching mshta.exe for HTA: $_" "ERROR" |
78 | 84 | } |
| 85 | +} else { |
| 86 | + Log-Message "HTA file not found at: $messagePath" "ERROR" |
79 | 87 | } |
80 | 88 |
|
81 | | -# Define the path to the post-logon message file located on the network share |
82 | | -$messagePath = "\\forest-logonserver-name\netlogon\broadcast-logonmessage\Broadcast-UserLogonMessageViaGPO.hta" |
83 | | - |
84 | | -# Execute the logon message display |
85 | | -Display-LogonMessage -messageFilePath $messagePath |
| 89 | +Log-Message "Script finished." |
| 90 | +exit 0 |
86 | 91 |
|
87 | | -# End of the script |
| 92 | +# End of script |
0 commit comments