|
<# |
|
|
|
BananaAcid 2022-2024 |
|
License MIT |
|
v1.0.3 |
|
|
|
To run this file and get PowerShellGSM installed, paste the following into your powershell: |
|
|
|
|
|
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://gist.githubusercontent.com/bananaacid/1dc9117571967b26ceabc972009137ae/raw/install_PowerShellGSM.ps1')) |
|
|
|
|
|
|
|
Changes: |
|
- 16.02.2024 fix for PalWorld config: parsed the replacement block (Sart-ServerProp) as well |
|
#> |
|
|
|
Function Main() { |
|
|
|
## Source file: https://github.com/patrix87/PowerShellGSM/archive/refs/tags/2.9.zip --> folder inside: PowerShellGSM-2.9.zip:.\PowerShellGSM-2.9\*.* |
|
## -> what a horrible naming party / dynamic every time. |
|
# $tag = "latest" |
|
# $file = "random_name.zip" |
|
# $url = "https://github.com/patrix87/PowerShellGSM/releases/download/$tag/$file" |
|
|
|
|
|
$url = "https://github.com/patrix87/PowerShellGSM/archive/refs/heads/main.zip" |
|
$tmpFile = "$env:TEMP\PowerShellGSM.main.zip"; |
|
# ---> Extracted filepath will always be PowerShellGSM-main ! |
|
|
|
|
|
|
|
$lastState = Get-Content ~\.PowerShellGSM -erroraction 'silentlycontinue' | ConvertFrom-Json -erroraction 'silentlycontinue' |
|
|
|
if ( -not $? ) { |
|
$lastState = [pscustomobject]@{ |
|
exPath = "" |
|
} |
|
} |
|
else { |
|
echo "Installation found in: $($lastState.exPath)" |
|
} |
|
|
|
|
|
## DOWNLOAD |
|
|
|
if (Test-Path $tmpFile) { |
|
$r = Read-Host "Download fresh PowerShellGSM files (Y/n)" |
|
if ($r -ne "" -and $r -ne "y" -and $r -ne "Y") { |
|
$noDl = $True |
|
} |
|
} |
|
|
|
if ($noDl -ne $True) { |
|
echo "downloading $url" |
|
Invoke-WebRequest $url -OutFile $tmpFile |
|
|
|
|
|
## EXTRACT |
|
|
|
if ($lastState.exPath -ne "") { $def = "to " + $lastState.exPath } else { $def = "here" } |
|
|
|
$r = Read-Host "Extract installation file $def (Y/n)" |
|
if ($r -eq "" -or $r -eq "y" -or $r -eq "Y") { |
|
if ($lastState.exPath -ne "") { $r = $lastState.exPath } else { $r = pwd } |
|
} |
|
else { |
|
$r = Read-Host "Installation path" |
|
} |
|
$exPath = $r |
|
|
|
echo "Installation path used: $exPath" |
|
|
|
Expand-Archive $tmpFile $env:TEMP -Force |
|
ni $exPath -ItemType Directory -Force >$null |
|
cp $env:TEMP\PowerShellGSM-main\* $exPath\ -Force -R |
|
rm $env:TEMP\PowerShellGSM-main -R -Force |
|
|
|
} |
|
else { |
|
if ($lastState.exPath -ne "") { $def = $lastState.exPath } else { $def = "here" } |
|
$r = Read-Host "Enter path to previous installation (default: $def)" |
|
if ($r -eq "") { |
|
if ($lastState.exPath -ne "") { $r = $lastState.exPath } else { $r = pwd } |
|
} |
|
|
|
$exPath = $r |
|
} |
|
|
|
|
|
## ACTIVATE TEMPLATE |
|
|
|
echo "Select a server template to add:" |
|
$Options = ls $exPath\templates |? {$_.Name -notlike '#*'} |% BaseName |
|
$Selection = Create-Menu -MenuOptions $Options -Columns "auto" -MaximumColumnWidth 20 -ShowCurrentSelection $True |
|
$tmplFile = $Options[$Selection] |
|
$cfgFile = "$tmplFile.psm1" |
|
|
|
if (Test-Path $exPath\configs\$cfgFile) { |
|
$r = Read-Host "Overwrite the config file for the selected server with new and blank one (backup will be created) (y/N)" |
|
if ($r -eq "" -or $r -eq "n" -or $r -eq "N") { |
|
$ignoreReplace = $True |
|
} |
|
else { |
|
# just to make sure ... |
|
$timestamp = Get-Date -format "yyyy-MM-dd_HH-mm-ss" |
|
cp $exPath\configs\$cfgFile $exPath\configs\$cfgFile.backup.$timestamp -Force |
|
cp $exPath\launchers\$tmplFile.cmd $exPath\launchers\$tmplFile.cmd.backup.$timestamp |
|
} |
|
} |
|
|
|
if ($ignoreReplace -ne $True) { |
|
cp $exPath\templates\$cfgFile $exPath\configs -Force |
|
cp $exPath\launchers\run.cmd $exPath\launchers\$tmplFile.cmd -Force |
|
} |
|
|
|
echo "To run the selected server for $tmplFile, run $exPath\launchers\$tmplFile.cmd" |
|
|
|
|
|
## change passwords |
|
|
|
$r = Read-Host "Change all passwords in the new config (Y/n)" |
|
if ($r -eq "" -or $r -eq "y" -or $r -eq "Y") { |
|
|
|
# get content |
|
$inputFile = gc $exPath\configs\$cfgFile -Raw |
|
|
|
# find description, key, value (password) |
|
$results = [Regex]::Matches($inputFile, "^[\s]+(?<desc>#.*)*\n^[\s]+(?<line>(?<key>[^#'\s]*Password[^=\s]*)[\s]*=[\s]*""(?<val>[^""]*)"")", "IgnoreCase,Multiline") |
|
|
|
$newFile = $inputFile |
|
|
|
For ($i = 0; $i -lt $results.count; $i++) { |
|
|
|
# ask for new password and show comment + old value |
|
Write-Host "$($results[$i].Groups['desc'].Value) -- currently: '$($results[$i].Groups['val'].Value)'" -ForegroundColor DarkGray |
|
$val = Read-Host "New password for '$($results[$i].Groups['key'].Value)' (empty for random)" |
|
|
|
if ($val -eq "") { |
|
$val = ((-join (((48..57)+(65..90)+(97..122)) * 80 |Get-Random -Count 8 |%{[char]$_})) -replace '0|O|o|I|l|1|5|S|s','A').ToLower() # if not toLower, add: |Y|y|V|v|K|k|W|w|P|p|C|c|X|x |
|
Write-Host "... random: $val" |
|
} |
|
# replace old value in line |
|
$a = '"' + $results[$i].Groups["val"].Value + '"' |
|
$b = '"' + $val + '"' |
|
$x = $results[$i].Groups["line"].Value -replace $a,$b |
|
|
|
# replace old row |
|
$newFile = $newFile -replace $results[$i].Groups["line"].Value,$x |
|
} |
|
|
|
Write-Host "" |
|
|
|
# write new content |
|
$newFile | Out-File $exPath\configs\$cfgFile |
|
} |
|
|
|
|
|
## SHOW CONFIG |
|
|
|
$r = Read-Host "Show config file to be edited manually (Y/n)" |
|
if ($r -eq "" -or $r -eq "y" -or $r -eq "Y") { |
|
notepad $exPath\configs\$cfgFile |
|
explorer /select,"$exPath\configs\$cfgFile" |
|
} |
|
|
|
|
|
## REMEMBER |
|
|
|
$lastState.exPath = Convert-Path $exPath |
|
ConvertTo-Json $lastState | Out-File ~\.PowerShellGSM |
|
|
|
} |
|
|
|
|
|
|
|
|
|
## MODULES |
|
|
|
|
|
# https://community.spiceworks.com/scripts/show/4785-create-menu-2-0-arrow-key-driven-powershell-menu-for-scripts |
|
# Modified by BananaAcid |
|
Function Create-Menu (){ |
|
#Start-Transcript "C:\_RRC\MenuLog.txt" |
|
Param( |
|
[Parameter(Mandatory=$True)][array]$MenuOptions, |
|
[Parameter(Mandatory=$True)][String]$Columns = "Auto", |
|
[Parameter(Mandatory=$False)][int]$MaximumColumnWidth=20, |
|
[Parameter(Mandatory=$False)][bool]$ShowCurrentSelection=$False |
|
) |
|
|
|
$consoleTop = $False; |
|
|
|
$MaxValue = $MenuOptions.count-1 |
|
$Selection = 0 |
|
$EnterPressed = $False |
|
|
|
If ($Columns -eq "Auto"){ |
|
$WindowWidth = (Get-Host).UI.RawUI.MaxWindowSize.Width |
|
$Columns = [Math]::Floor($WindowWidth/($MaximumColumnWidth+2)) |
|
} |
|
|
|
If ([int]$Columns -gt $MenuOptions.count){ |
|
$Columns = $MenuOptions.count |
|
} |
|
|
|
$RowQty = ([Math]::Ceiling(($MaxValue+1)/$Columns)) |
|
|
|
|
|
Function ClearHost () { |
|
if ($consoleTop -eq $False) { |
|
$consoleTop = [Console]::CursorTop - $RowQty |
|
} |
|
[Console]::SetCursorPosition(0, $consoleTop) |
|
} |
|
|
|
|
|
$MenuListing = @() |
|
|
|
For($i=0; $i -lt $Columns; $i++){ |
|
|
|
$ScratchArray = @() |
|
|
|
For($j=($RowQty*$i); $j -lt ($RowQty*($i+1)); $j++){ |
|
|
|
$ScratchArray += $MenuOptions[$j] |
|
} |
|
|
|
$ColWidth = ($ScratchArray |Measure-Object -Maximum -Property length).Maximum |
|
|
|
If ($ColWidth -gt $MaximumColumnWidth){ |
|
$ColWidth = $MaximumColumnWidth-1 |
|
} |
|
|
|
For($j=0; $j -lt $ScratchArray.count; $j++){ |
|
|
|
If(($ScratchArray[$j]).length -gt $($MaximumColumnWidth -2)){ |
|
$ScratchArray[$j] = $($ScratchArray[$j]).Substring(0,$($MaximumColumnWidth-4)) |
|
$ScratchArray[$j] = "$($ScratchArray[$j])..." |
|
} Else { |
|
|
|
For ($k=$ScratchArray[$j].length; $k -lt $ColWidth; $k++){ |
|
$ScratchArray[$j] = "$($ScratchArray[$j]) " |
|
} |
|
|
|
} |
|
|
|
$ScratchArray[$j] = " $($ScratchArray[$j]) " |
|
} |
|
$MenuListing += $ScratchArray |
|
} |
|
|
|
While($EnterPressed -eq $False){ |
|
|
|
If ($ShowCurrentSelection -eq $True){ |
|
$Host.UI.RawUI.WindowTitle = "CURRENT SELECTION: $($MenuOptions[$Selection])" |
|
} |
|
|
|
For ($i=0; $i -lt $RowQty; $i++){ |
|
|
|
For($j=0; $j -le (($Columns-1)*$RowQty);$j+=$RowQty){ |
|
|
|
If($j -eq (($Columns-1)*$RowQty)){ |
|
If(($i+$j) -eq $Selection){ |
|
Write-Host -BackgroundColor cyan -ForegroundColor Black "$($MenuListing[$i+$j])" |
|
} Else { |
|
Write-Host "$($MenuListing[$i+$j])" |
|
} |
|
} Else { |
|
|
|
If(($i+$j) -eq $Selection){ |
|
Write-Host -BackgroundColor Cyan -ForegroundColor Black "$($MenuListing[$i+$j])" -NoNewline |
|
} Else { |
|
Write-Host "$($MenuListing[$i+$j])" -NoNewline |
|
} |
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
#Uncomment the below line if you need to do live debugging of the current index selection. It will put it in green below the selection listing. |
|
#Write-Host -ForegroundColor Green "$Selection" |
|
|
|
$KeyInput = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown").virtualkeycode |
|
|
|
Switch($KeyInput){ |
|
13{ |
|
$EnterPressed = $True |
|
Return $Selection |
|
ClearHost |
|
break |
|
} |
|
|
|
37{ #Left |
|
If ($Selection -ge $RowQty){ |
|
$Selection -= $RowQty |
|
} Else { |
|
$Selection += ($Columns-1)*$RowQty |
|
} |
|
ClearHost |
|
break |
|
} |
|
|
|
38{ #Up |
|
If ((($Selection+$RowQty)%$RowQty) -eq 0){ |
|
$Selection += $RowQty - 1 |
|
} Else { |
|
$Selection -= 1 |
|
} |
|
ClearHost |
|
break |
|
} |
|
|
|
39{ #Right |
|
If ([Math]::Ceiling($Selection/$RowQty) -eq $Columns -or ($Selection/$RowQty)+1 -eq $Columns){ |
|
$Selection -= ($Columns-1)*$RowQty |
|
} Else { |
|
$Selection += $RowQty |
|
} |
|
ClearHost |
|
break |
|
} |
|
|
|
40{ #Down |
|
If ((($Selection+1)%$RowQty) -eq 0 -or $Selection -eq $MaxValue){ |
|
$Selection = ([Math]::Floor(($Selection)/$RowQty))*$RowQty |
|
|
|
} Else { |
|
$Selection += 1 |
|
} |
|
ClearHost |
|
break |
|
} |
|
Default{ |
|
ClearHost |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
Main |
throws a bunch of errors on my side and leaves me with a blank .ps1