albert gist felülvizsgálása . Revízióhoz ugrás
1 file changed, 396 insertions
Setup-CoreutilsLinks.ps1(fájl létrehozva)
@@ -0,0 +1,396 @@ | |||
1 | + | <# | |
2 | + | .SYNOPSIS | |
3 | + | Automates the setup of uutils/coreutils on Windows by creating batch file shims | |
4 | + | for its commands and assisting with PATH configuration. | |
5 | + | ||
6 | + | .DESCRIPTION | |
7 | + | This script attempts to locate an existing uutils/coreutils installation. | |
8 | + | If not found, it can optionally install it via winget. | |
9 | + | It then dynamically fetches the list of available utilities from coreutils.exe | |
10 | + | and creates batch file shims (e.g., ls.bat, cat.bat) in a specified directory. | |
11 | + | These shims call the main coreutils.exe with the appropriate command. | |
12 | + | Finally, it can help add this shims directory to the User's PATH environment variable. | |
13 | + | ||
14 | + | .PARAMETER ShimsDirectory | |
15 | + | The directory where the batch file shims for coreutils commands will be created. | |
16 | + | Defaults to "$env:LOCALAPPDATA\uutils-shims". | |
17 | + | ||
18 | + | .PARAMETER ForceInstall | |
19 | + | If specified, and coreutils is not found, the script will attempt to install | |
20 | + | it via winget without prompting for confirmation. | |
21 | + | ||
22 | + | .PARAMETER ForcePathAddition | |
23 | + | If specified, and the ShimsDirectory is not in the PATH, the script will | |
24 | + | attempt to add it to the User PATH without prompting for confirmation. | |
25 | + | ||
26 | + | .PARAMETER SkipPathCheck | |
27 | + | If specified, the script will not check or offer to modify the PATH environment variable. | |
28 | + | ||
29 | + | .EXAMPLE | |
30 | + | .\Setup-CoreutilsShims.ps1 | |
31 | + | Runs the script with default settings and interactive prompts. | |
32 | + | ||
33 | + | .EXAMPLE | |
34 | + | .\Setup-CoreutilsShims.ps1 -ShimsDirectory "C:\myCLItools" -ForceInstall -ForcePathAddition | |
35 | + | Runs the script, creates shims in "C:\myCLItools", and attempts to install | |
36 | + | coreutils and add the directory to PATH without prompting. | |
37 | + | ||
38 | + | .EXAMPLE | |
39 | + | .\Setup-CoreutilsShims.ps1 -Verbose | |
40 | + | Runs the script with detailed verbose output. | |
41 | + | ||
42 | + | .NOTES | |
43 | + | - Changes to the PATH environment variable typically require restarting terminal | |
44 | + | sessions or logging out and back in to take effect. | |
45 | + | - If you want coreutils commands (like 'dir', 'sort') to override built-in | |
46 | + | Windows commands, the ShimsDirectory may need to be placed *before* | |
47 | + | C:\Windows\System32 in your PATH environment variable. This script adds | |
48 | + | it to the end of the User PATH by default if modification is chosen. | |
49 | + | #> | |
50 | + | [CmdletBinding(SupportsShouldProcess = $true)] | |
51 | + | param( | |
52 | + | [string]$ShimsDirectory = (Join-Path $env:LOCALAPPDATA "uutils-shims"), | |
53 | + | ||
54 | + | [switch]$ForceInstall, | |
55 | + | ||
56 | + | [switch]$ForcePathAddition, | |
57 | + | ||
58 | + | [switch]$SkipPathCheck | |
59 | + | ) | |
60 | + | ||
61 | + | # Script-level error action preference | |
62 | + | $ErrorActionPreference = "Stop" # Stop on terminating errors | |
63 | + | ||
64 | + | # --- Helper Functions --- | |
65 | + | function Show-Menu ([string]$Title, [string]$PromptMessage) { | |
66 | + | Write-Host "`n--- $Title ---" | |
67 | + | $options = @( | |
68 | + | [System.Management.Automation.Host.ChoiceDescription]::new("&Yes", "Proceed with this action.") | |
69 | + | [System.Management.Automation.Host.ChoiceDescription]::new("&No", "Skip this action.") | |
70 | + | ) | |
71 | + | $decision = $host.UI.PromptForChoice($Title, $PromptMessage, $options, 0) | |
72 | + | return ($decision -eq 0) # 0 is Yes | |
73 | + | } | |
74 | + | ||
75 | + | # --- Core Logic Functions --- | |
76 | + | ||
77 | + | function Find-CoreutilsExecutable { | |
78 | + | Write-Verbose "Attempting to find coreutils.exe..." | |
79 | + | ||
80 | + | # 1. Try Get-Command (if already in PATH or an alias exists) | |
81 | + | Write-Verbose "Checking PATH for coreutils..." | |
82 | + | $coreutilsCmd = Get-Command coreutils -ErrorAction SilentlyContinue | |
83 | + | if ($coreutilsCmd -and $coreutilsCmd.Source -and (Test-Path $coreutilsCmd.Source -PathType Leaf)) { | |
84 | + | Write-Host "Found coreutils via Get-Command at: $($coreutilsCmd.Source)" -ForegroundColor Green | |
85 | + | return $coreutilsCmd.Source | |
86 | + | } | |
87 | + | ||
88 | + | # 2. Try known winget installation path pattern | |
89 | + | Write-Verbose "Checking common winget installation paths..." | |
90 | + | $wingetPackagesBase = Join-Path $env:LOCALAPPDATA "Microsoft\WinGet\Packages" | |
91 | + | $coreutilsPackageDirPattern = "uutils.coreutils_Microsoft.Winget.Source_8wekyb3d8bbwe" # Common package identifier | |
92 | + | ||
93 | + | if (Test-Path $wingetPackagesBase) { | |
94 | + | $packageInstallDir = Get-ChildItem -Path $wingetPackagesBase -Directory -Filter $coreutilsPackageDirPattern -ErrorAction SilentlyContinue | | |
95 | + | Select-Object -First 1 | |
96 | + | if ($packageInstallDir) { | |
97 | + | Write-Verbose "Found potential coreutils package directory: $($packageInstallDir.FullName)" | |
98 | + | # Find the latest versioned subdirectory (often contains version string or arch) | |
99 | + | $latestVersionDir = Get-ChildItem -Path $packageInstallDir.FullName -Directory -ErrorAction SilentlyContinue | | |
100 | + | Sort-Object -Property Name -Descending | # Sort by name, hoping newer versions list first | |
101 | + | Select-Object -First 1 | |
102 | + | if ($latestVersionDir) { | |
103 | + | $potentialPath = Join-Path $latestVersionDir.FullName "coreutils.exe" | |
104 | + | Write-Verbose "Checking for coreutils.exe in: $potentialPath" | |
105 | + | if (Test-Path $potentialPath -PathType Leaf) { | |
106 | + | Write-Host "Found coreutils in winget package directory: $potentialPath" -ForegroundColor Green | |
107 | + | return $potentialPath | |
108 | + | } | |
109 | + | } else { | |
110 | + | Write-Verbose "No version subdirectories found under $($packageInstallDir.FullName)" | |
111 | + | } | |
112 | + | } else { | |
113 | + | Write-Verbose "Coreutils package directory pattern not found under $wingetPackagesBase" | |
114 | + | } | |
115 | + | } else { | |
116 | + | Write-Verbose "Winget packages base directory not found: $wingetPackagesBase" | |
117 | + | } | |
118 | + | ||
119 | + | # 3. Not found, offer to install via winget | |
120 | + | Write-Warning "coreutils.exe not found on this system." | |
121 | + | $shouldInstall = $false | |
122 | + | if ($ForceInstall) { | |
123 | + | $shouldInstall = $true | |
124 | + | } else { | |
125 | + | if ($PSCmdlet.ShouldProcess("Install uutils/coreutils via winget", "Coreutils not found. Do you want to attempt installation?")) { | |
126 | + | $shouldInstall = Show-Menu -Title "Install Coreutils" -PromptMessage "coreutils.exe was not found. Would you like to attempt to install it using winget? (This will run 'winget install uutils.coreutils --source winget -e --accept-package-agreements --accept-source-agreements')" | |
127 | + | } | |
128 | + | } | |
129 | + | ||
130 | + | if ($shouldInstall) { | |
131 | + | Write-Host "Attempting to install uutils/coreutils via winget..." | |
132 | + | $wingetCmd = Get-Command winget -ErrorAction SilentlyContinue | |
133 | + | if (-not $wingetCmd) { | |
134 | + | Write-Error "winget command not found. Cannot install coreutils automatically." | |
135 | + | return $null | |
136 | + | } | |
137 | + | try { | |
138 | + | $installArgs = "install uutils.coreutils --source winget -e --accept-package-agreements --accept-source-agreements" | |
139 | + | Write-Verbose "Running: winget $installArgs" | |
140 | + | $process = Start-Process winget -ArgumentList $installArgs -Wait -PassThru -WindowStyle Minimized | |
141 | + | if ($process.ExitCode -eq 0) { | |
142 | + | Write-Host "coreutils installed successfully via winget." -ForegroundColor Green | |
143 | + | # Re-attempt find after installation | |
144 | + | Write-Verbose "Re-checking for coreutils.exe after installation..." | |
145 | + | $coreutilsCmdAfterInstall = Get-Command coreutils -ErrorAction SilentlyContinue | |
146 | + | if ($coreutilsCmdAfterInstall -and $coreutilsCmdAfterInstall.Source -and (Test-Path $coreutilsCmdAfterInstall.Source -PathType Leaf)) { | |
147 | + | Write-Host "Found coreutils after install at: $($coreutilsCmdAfterInstall.Source)" -ForegroundColor Green | |
148 | + | return $coreutilsCmdAfterInstall.Source | |
149 | + | } | |
150 | + | # If Get-Command doesn't find it immediately, try the winget path again | |
151 | + | if (Test-Path $wingetPackagesBase) { | |
152 | + | $packageInstallDir = Get-ChildItem -Path $wingetPackagesBase -Directory -Filter $coreutilsPackageDirPattern -ErrorAction SilentlyContinue | Select-Object -First 1 | |
153 | + | if ($packageInstallDir) { | |
154 | + | $latestVersionDir = Get-ChildItem -Path $packageInstallDir.FullName -Directory -ErrorAction SilentlyContinue | Sort-Object Name -Descending | Select-Object -First 1 | |
155 | + | if ($latestVersionDir) { | |
156 | + | $potentialPath = Join-Path $latestVersionDir.FullName "coreutils.exe" | |
157 | + | if (Test-Path $potentialPath -PathType Leaf) { | |
158 | + | Write-Host "Found coreutils in winget package directory after install: $potentialPath" -ForegroundColor Green | |
159 | + | return $potentialPath | |
160 | + | } | |
161 | + | } | |
162 | + | } | |
163 | + | } | |
164 | + | Write-Warning "coreutils installed, but could not immediately locate coreutils.exe. You might need to restart your terminal or find it manually." | |
165 | + | return $null | |
166 | + | } else { | |
167 | + | Write-Error "winget installation failed with exit code $($process.ExitCode)." | |
168 | + | return $null | |
169 | + | } | |
170 | + | } catch { | |
171 | + | Write-Error "An error occurred during winget installation: $($_.Exception.Message)" | |
172 | + | return $null | |
173 | + | } | |
174 | + | } | |
175 | + | Write-Error "coreutils.exe could not be found or installed." | |
176 | + | return $null | |
177 | + | } | |
178 | + | ||
179 | + | function Get-CoreutilsCommands ([string]$CoreutilsExePath) { | |
180 | + | Write-Verbose "Attempting to get command list from '$CoreutilsExePath --list'..." | |
181 | + | $Commands = $null | |
182 | + | try { | |
183 | + | $processInfo = New-Object System.Diagnostics.ProcessStartInfo | |
184 | + | $processInfo.FileName = $CoreutilsExePath | |
185 | + | $processInfo.Arguments = "--list" | |
186 | + | $processInfo.RedirectStandardOutput = $true | |
187 | + | $processInfo.RedirectStandardError = $true | |
188 | + | $processInfo.UseShellExecute = $false | |
189 | + | $processInfo.CreateNoWindow = $true | |
190 | + | ||
191 | + | $process = New-Object System.Diagnostics.Process | |
192 | + | $process.StartInfo = $processInfo | |
193 | + | $process.Start() | Out-Null | |
194 | + | ||
195 | + | $output = $process.StandardOutput.ReadToEnd() | |
196 | + | $errors = $process.StandardError.ReadToEnd() | |
197 | + | $process.WaitForExit() | |
198 | + | $exitCode = $process.ExitCode | |
199 | + | ||
200 | + | if ($exitCode -ne 0 -or [string]::IsNullOrWhiteSpace($output)) { | |
201 | + | Write-Warning "Command '$CoreutilsExePath --list' failed or returned empty stdout." | |
202 | + | Write-Warning "Exit code: $exitCode" | |
203 | + | if (-not [string]::IsNullOrWhiteSpace($errors)) { | |
204 | + | Write-Warning "Error output from coreutils --list:`n$errors" | |
205 | + | } | |
206 | + | } else { | |
207 | + | Write-Verbose "Raw output from coreutils --list:`n$output" | |
208 | + | $CommandLines = $output.Split([System.Environment]::NewLine) | |
209 | + | $ProcessingCommands = $false | |
210 | + | $CombinedCommandLines = "" | |
211 | + | ||
212 | + | if ($output -match "Currently defined functions:") { | |
213 | + | Write-Verbose "Parsing based on 'Currently defined functions:' marker." | |
214 | + | foreach ($Line in $CommandLines) { | |
215 | + | if ($ProcessingCommands) { | |
216 | + | $TrimmedLine = $Line.Trim() | |
217 | + | if (-not [string]::IsNullOrWhiteSpace($TrimmedLine)) { | |
218 | + | $CombinedCommandLines += $TrimmedLine | |
219 | + | } | |
220 | + | } | |
221 | + | if ($Line -match "Currently defined functions:") { | |
222 | + | $ProcessingCommands = $true | |
223 | + | } | |
224 | + | } | |
225 | + | if (-not [string]::IsNullOrWhiteSpace($CombinedCommandLines)) { | |
226 | + | $Commands = $CombinedCommandLines -split ',' | ForEach-Object { $_.Trim() } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | |
227 | + | } | |
228 | + | } else { | |
229 | + | Write-Verbose "Attempting to parse as one command per line (fallback)." | |
230 | + | $Commands = $CommandLines | ForEach-Object { $_.Trim() } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) -and $_ -notmatch "^Usage:" -and $_ -notmatch "^Options:" -and $_ -notmatch "^Currently defined functions:" -and $_ -notmatch "multi-call binary" } | |
231 | + | } | |
232 | + | ||
233 | + | if ($Commands -and $Commands.Length -gt 0) { | |
234 | + | Write-Host "Successfully parsed $($Commands.Length) commands dynamically from coreutils --list." -ForegroundColor Green | |
235 | + | } else { | |
236 | + | Write-Warning "Dynamically parsed 0 commands. The output format might have changed or was unexpected." | |
237 | + | } | |
238 | + | } | |
239 | + | } catch { | |
240 | + | Write-Warning "An error occurred while trying to execute or parse '$CoreutilsExePath --list': $($_.Exception.Message)" | |
241 | + | } | |
242 | + | ||
243 | + | if (-not $Commands -or $Commands.Length -eq 0) { | |
244 | + | Write-Warning "Dynamic command fetching failed or yielded no commands. Using a predefined fallback list." | |
245 | + | $Commands = @( | |
246 | + | "arch", "b2sum", "b3sum", "base32", "base64", "basename", "basenc", "cat", "cksum", "comm", "cp", | |
247 | + | "csplit", "cut", "date", "dd", "df", "dir", "dircolors", "dirname", "du", "echo", "env", | |
248 | + | "expand", "expr", "factor", "false", "fmt", "fold", "hashsum", "head", "hostname", "join", | |
249 | + | "link", "ln", "ls", "md5sum", "mkdir", "mktemp", "more", "mv", "nl", "nproc", "numfmt", | |
250 | + | "od", "paste", "pr", "printenv", "printf", "ptx", "pwd", "readlink", "realpath", "rm", | |
251 | + | "rmdir", "seq", "sha1sum", "sha224sum", "sha256sum", "sha3-224sum", "sha3-256sum", | |
252 | + | "sha3-384sum", "sha3-512sum", "sha384sum", "sha3sum", "sha512sum", "shake128sum", | |
253 | + | "shake256sum", "shred", "shuf", "sleep", "sort", "split", "sum", "sync", "tac", "tail", | |
254 | + | "tee", "test", "touch", "tr", "true", "truncate", "tsort", "uname", "unexpand", "uniq", | |
255 | + | "unlink", "vdir", "wc", "whoami", "yes", "[" | |
256 | + | ) | |
257 | + | Write-Host "Using fallback list with $($Commands.Length) commands." | |
258 | + | } | |
259 | + | return $Commands | |
260 | + | } | |
261 | + | ||
262 | + | function Create-UtilityShims ([string]$CoreutilsExePath, [array]$Commands, [string]$TargetShimsDirectory) { | |
263 | + | Write-Host "`n--- Creating Utility Batch File Shims ---" | |
264 | + | Write-Host "Coreutils Executable: $CoreutilsExePath" | |
265 | + | Write-Host "Shims Directory: $TargetShimsDirectory" | |
266 | + | ||
267 | + | if (-not (Test-Path $TargetShimsDirectory)) { | |
268 | + | Write-Verbose "Shims directory '$TargetShimsDirectory' does not exist. Attempting to create it." | |
269 | + | if ($PSCmdlet.ShouldProcess("Create directory '$TargetShimsDirectory'")) { | |
270 | + | try { | |
271 | + | New-Item -ItemType Directory -Path $TargetShimsDirectory -Force | Out-Null | |
272 | + | Write-Host "Created directory '$TargetShimsDirectory'" -ForegroundColor Green | |
273 | + | } catch { | |
274 | + | Write-Error "Failed to create directory '$TargetShimsDirectory': $($_.Exception.Message)" | |
275 | + | return | |
276 | + | } | |
277 | + | } else { | |
278 | + | Write-Warning "Directory creation skipped by user. Cannot create shims." | |
279 | + | return | |
280 | + | } | |
281 | + | } | |
282 | + | ||
283 | + | Write-Host "Creating batch file shims..." | |
284 | + | $CreatedCount = 0 | |
285 | + | $SkippedCount = 0 | |
286 | + | $FailedCount = 0 | |
287 | + | ||
288 | + | foreach ($CommandNameInList in $Commands) { | |
289 | + | $ShimmedCommandName = $CommandNameInList # This is the command to pass to coreutils.exe | |
290 | + | $BatchFileName = "$CommandNameInList.bat" | |
291 | + | ||
292 | + | if ($CommandNameInList -eq "[") { | |
293 | + | $BatchFileName = "bracket.bat" # Use a valid filename for the '[' command | |
294 | + | # $ShimmedCommandName is already "[" which is correct | |
295 | + | } | |
296 | + | ||
297 | + | $BatchPath = Join-Path $TargetShimsDirectory $BatchFileName | |
298 | + | ||
299 | + | if (Test-Path $BatchPath) { | |
300 | + | Write-Verbose "Skipping: Batch file '$BatchPath' already exists." | |
301 | + | $SkippedCount++ | |
302 | + | continue | |
303 | + | } | |
304 | + | ||
305 | + | # Content of the batch file: @echo off, then "path/to/coreutils.exe" command %* | |
306 | + | # Ensure $CoreutilsExePath is quoted in case it has spaces. | |
307 | + | # $ShimmedCommandName is the command name (e.g., "ls", "uname", "[") | |
308 | + | $BatchContent = "@echo off`r`n`"$CoreutilsExePath`" $ShimmedCommandName %*" | |
309 | + | ||
310 | + | if ($PSCmdlet.ShouldProcess("Create batch file shim '$BatchPath' for command '$ShimmedCommandName'")) { | |
311 | + | try { | |
312 | + | Set-Content -Path $BatchPath -Value $BatchContent -Encoding Ascii -Force | |
313 | + | Write-Verbose "Successfully created batch file: $BatchPath" | |
314 | + | $CreatedCount++ | |
315 | + | } catch { | |
316 | + | Write-Warning "Failed to create batch file '$BatchPath': $($_.Exception.Message)" | |
317 | + | $FailedCount++ | |
318 | + | } | |
319 | + | } else { | |
320 | + | Write-Verbose "Skipped creating batch file '$BatchPath' due to ShouldProcess." | |
321 | + | $SkippedCount++ | |
322 | + | } | |
323 | + | } | |
324 | + | Write-Host "Shim creation summary: $CreatedCount created, $SkippedCount skipped, $FailedCount failed." -ForegroundColor Cyan | |
325 | + | } | |
326 | + | ||
327 | + | function Manage-PathEnvironmentVariable ([string]$DirectoryToAdd) { | |
328 | + | Write-Host "`n--- PATH Environment Variable Check ---" | |
329 | + | $currentUserPath = [System.Environment]::GetEnvironmentVariable("Path", "User") | |
330 | + | $pathParts = $currentUserPath -split ';' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | |
331 | + | ||
332 | + | if ($pathParts -contains $DirectoryToAdd) { | |
333 | + | Write-Host "Directory '$DirectoryToAdd' is already in your User PATH." -ForegroundColor Green | |
334 | + | return | |
335 | + | } | |
336 | + | ||
337 | + | Write-Warning "Directory '$DirectoryToAdd' is NOT in your User PATH." | |
338 | + | $shouldAddToPath = $false | |
339 | + | if ($ForcePathAddition) { | |
340 | + | $shouldAddToPath = $true | |
341 | + | } else { | |
342 | + | if ($PSCmdlet.ShouldProcess("Add '$DirectoryToAdd' to User PATH", "This will make the commands available in new terminal sessions.")) { | |
343 | + | $shouldAddToPath = Show-Menu -Title "Update User PATH" -PromptMessage "Would you like to add '$DirectoryToAdd' to your User PATH environment variable?" | |
344 | + | } | |
345 | + | } | |
346 | + | ||
347 | + | if ($shouldAddToPath) { | |
348 | + | if ($PSCmdlet.ShouldProcess("Set User PATH = '$currentUserPath;$DirectoryToAdd'")) { | |
349 | + | try { | |
350 | + | $newPath = ($pathParts + $DirectoryToAdd) -join ';' | |
351 | + | [System.Environment]::SetEnvironmentVariable("Path", $newPath, "User") | |
352 | + | Write-Host "Successfully added '$DirectoryToAdd' to your User PATH." -ForegroundColor Green | |
353 | + | Write-Host "IMPORTANT: You need to RESTART your terminal (PowerShell, Command Prompt, etc.) or log out and back in for this change to take full effect." -ForegroundColor Yellow | |
354 | + | Write-Host "Note: For coreutils commands like 'dir' or 'sort' to override built-in Windows commands, '$DirectoryToAdd' may need to be placed *before* C:\Windows\System32 in your PATH. This script added it to the end of your User PATH." -ForegroundColor Yellow | |
355 | + | } catch { | |
356 | + | Write-Error "Failed to add '$DirectoryToAdd' to User PATH: $($_.Exception.Message)" | |
357 | + | } | |
358 | + | } else { | |
359 | + | Write-Warning "PATH modification skipped by user (ShouldProcess)." | |
360 | + | } | |
361 | + | } else { | |
362 | + | Write-Host "Skipped adding '$DirectoryToAdd' to User PATH." | |
363 | + | } | |
364 | + | } | |
365 | + | ||
366 | + | # --- Main Script Execution --- | |
367 | + | Write-Host "Starting uutils/coreutils Batch Shim Setup Script..." -ForegroundColor Magenta | |
368 | + | ||
369 | + | # Step 1: Find Coreutils Executable | |
370 | + | $coreutilsExe = Find-CoreutilsExecutable | |
371 | + | if (-not $coreutilsExe) { | |
372 | + | Write-Error "Could not locate or install coreutils.exe. Script cannot continue." | |
373 | + | exit 1 | |
374 | + | } | |
375 | + | Write-Host "Using coreutils at: $coreutilsExe" -ForegroundColor Cyan | |
376 | + | ||
377 | + | # Step 2: Get Command List | |
378 | + | $commandsToShim = Get-CoreutilsCommands -CoreutilsExePath $coreutilsExe | |
379 | + | if (-not $commandsToShim -or $commandsToShim.Length -eq 0) { | |
380 | + | Write-Error "Could not determine the list of coreutils commands. Script cannot continue." | |
381 | + | exit 1 | |
382 | + | } | |
383 | + | ||
384 | + | # Step 3: Create Utility Shims | |
385 | + | Create-UtilityShims -CoreutilsExePath $coreutilsExe -Commands $commandsToShim -TargetShimsDirectory $ShimsDirectory | |
386 | + | ||
387 | + | # Step 4: Manage PATH (unless skipped) | |
388 | + | if (-not $SkipPathCheck) { | |
389 | + | Manage-PathEnvironmentVariable -DirectoryToAdd $ShimsDirectory | |
390 | + | } else { | |
391 | + | Write-Host "`nSkipping PATH environment variable check as per -SkipPathCheck parameter." | |
392 | + | } | |
393 | + | ||
394 | + | Write-Host "`n--- Script Finished ---" -ForegroundColor Magenta | |
395 | + | Write-Host "If PATH was modified, remember to restart your terminal sessions." | |
396 | + | Write-Host "You can now try running commands like 'ls', 'cat', 'uname', 'bracket ... ]', etc." |
Újabb
Régebbi