Blaupausen je Kunde, Datei-Uploads, RDP-Verknuepfungen, Bloatware-Entfernung
- Blaupausen (blueprints\) mit Kunde/Beschreibung, gruppierte Ansicht, Duplizieren/Export, Schnellauswahl auf der Uebersicht, 2 Beispiele - Upload von Setups (EXE/MSI/MSIX/PS1/CMD) per Drag & Drop inkl. gespeicherter Silent-Parameter; Upload von Icons und .rdp-Dateien - RDP-Verknuepfungen fuer alle Benutzer: Generator (Gateway, RemoteApp, Umleitungen) oder hochgeladene .rdp-Dateien - Bloatware-Tab: Store-Apps, Hersteller-Tools, Testversionen, vorinstalliertes Office/OneNote (C2R) und OneDrive entfernen; Katalog in config/bloatware.json, auch als Schritt in Blaupausen - Fix: Top-Level-JSON-Arrays (Vorlagen) wurden falsch serialisiert Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
+294
-8
@@ -190,12 +190,22 @@ function Install-Apps {
|
||||
$file = $a.path
|
||||
if (-not [IO.Path]::IsPathRooted($file)) { $file = Join-Path $global:KdsRoot $file }
|
||||
if (-not (Test-Path $file)) { throw "Installer nicht gefunden: $file" }
|
||||
if ($file -like '*.msi') {
|
||||
$p = Start-Process msiexec.exe -ArgumentList "/i `"$file`" /qn /norestart $($a.args)" -Wait -PassThru
|
||||
} else {
|
||||
$p = Start-Process -FilePath $file -ArgumentList $a.args -Wait -PassThru
|
||||
$ext = [IO.Path]::GetExtension($file).ToLower()
|
||||
$sp = @{ Wait = $true; PassThru = $true; WorkingDirectory = (Split-Path $file) }
|
||||
switch ($ext) {
|
||||
'.msi' { $sp.FilePath = 'msiexec.exe'; $sp.ArgumentList = "/i `"$file`" /qn /norestart $($a.args)" }
|
||||
'.ps1' { $sp.FilePath = 'powershell.exe'; $sp.ArgumentList = "-NoProfile -ExecutionPolicy Bypass -File `"$file`" $($a.args)" }
|
||||
{ $_ -in '.cmd', '.bat' } { $sp.FilePath = 'cmd.exe'; $sp.ArgumentList = "/c `"`"$file`" $($a.args)`"" }
|
||||
{ $_ -in '.msix', '.msixbundle', '.appx', '.appxbundle' } { $sp = $null }
|
||||
default { $sp.FilePath = $file; if ($a.args) { $sp.ArgumentList = $a.args } }
|
||||
}
|
||||
if ($sp) {
|
||||
$code = (Start-Process @sp).ExitCode
|
||||
} else {
|
||||
# Paket fuer alle (auch kuenftige) Benutzer bereitstellen
|
||||
Add-AppxProvisionedPackage -Online -PackagePath $file -SkipLicense | Out-Null
|
||||
$code = 0
|
||||
}
|
||||
$code = $p.ExitCode
|
||||
} else {
|
||||
$src = if ($a.source) { $a.source } else { 'winget' }
|
||||
$base = @('install', '--id', $a.id, '--exact', '--source', $src, '--silent',
|
||||
@@ -334,10 +344,14 @@ function Get-PublicDesktop { [Environment]::GetFolderPath('CommonDesktopDirector
|
||||
function Get-PublicShortcuts {
|
||||
$d = Get-PublicDesktop
|
||||
$sh = New-Object -ComObject WScript.Shell
|
||||
@(Get-ChildItem $d -File | Where-Object { $_.Extension -in '.lnk', '.url' } | ForEach-Object {
|
||||
@(Get-ChildItem $d -File | Where-Object { $_.Extension -in '.lnk', '.url', '.rdp' } | ForEach-Object {
|
||||
$target = ''
|
||||
if ($_.Extension -eq '.lnk') { $target = $sh.CreateShortcut($_.FullName).TargetPath }
|
||||
else { $m = Select-String -Path $_.FullName -Pattern '^URL=(.*)$' | Select-Object -First 1; if ($m) { $target = $m.Matches[0].Groups[1].Value } }
|
||||
else {
|
||||
$pat = if ($_.Extension -eq '.rdp') { '^full address:s:(.*)$' } else { '^URL=(.*)$' }
|
||||
$m = Select-String -Path $_.FullName -Pattern $pat | Select-Object -First 1
|
||||
if ($m) { $target = [string]$m.Matches[0].Groups[1].Value }
|
||||
}
|
||||
[pscustomobject]@{ file = $_.Name; name = $_.BaseName; type = $_.Extension.TrimStart('.'); target = $target }
|
||||
})
|
||||
}
|
||||
@@ -361,7 +375,17 @@ function New-PublicShortcut {
|
||||
$safe = ($S.name -replace '[\\/:*?"<>|]', '_').Trim()
|
||||
if (-not $safe) { throw 'Name fehlt' }
|
||||
$icon = Resolve-IconPath $S.icon
|
||||
if ($S.type -eq 'url') {
|
||||
if ($S.type -eq 'rdp') {
|
||||
$file = Join-Path $d "$safe.rdp"
|
||||
if ($S.rdpFile) {
|
||||
# hochgeladene .rdp-Datei vom Stick verteilen
|
||||
$src = Join-Path $global:KdsRoot "rdp\$(Split-Path $S.rdpFile -Leaf)"
|
||||
if (-not (Test-Path $src)) { throw "RDP-Datei nicht gefunden: $src" }
|
||||
Copy-Item $src $file -Force
|
||||
} else {
|
||||
Set-Content -Path $file -Value (New-RdpContent $S.rdp) -Encoding Unicode
|
||||
}
|
||||
} elseif ($S.type -eq 'url') {
|
||||
$file = Join-Path $d "$safe.url"
|
||||
$c = "[InternetShortcut]`r`nURL=$($S.target)`r`n"
|
||||
if ($icon) { $c += "IconFile=$icon`r`nIconIndex=0`r`n" }
|
||||
@@ -397,6 +421,123 @@ function Set-DesktopShortcuts {
|
||||
}
|
||||
}
|
||||
|
||||
function New-RdpContent {
|
||||
# Erzeugt den Inhalt einer .rdp-Datei aus den Formularwerten
|
||||
param($R)
|
||||
if (-not $R.host) { throw 'RDP: Server/Host fehlt' }
|
||||
$b = { param($v) if (Test-True $v) { 1 } else { 0 } }
|
||||
$addr = $R.host
|
||||
if ($R.port -and "$($R.port)" -ne '3389') { $addr += ":$($R.port)" }
|
||||
$l = @(
|
||||
"full address:s:$addr"
|
||||
"screen mode id:i:$(if (Test-True $R.fullscreen) { 2 } else { 1 })"
|
||||
"use multimon:i:$(& $b $R.multimon)"
|
||||
'dynamic resolution:i:1'
|
||||
'smart sizing:i:1'
|
||||
"redirectclipboard:i:$(& $b $R.clipboard)"
|
||||
"redirectprinters:i:$(& $b $R.printers)"
|
||||
"redirectsmartcards:i:$(& $b $R.smartcards)"
|
||||
"drivestoredirect:s:$(if (Test-True $R.drives) { '*' } else { '' })"
|
||||
"audiomode:i:$(switch ($R.audio) { 'remote' { 1 } 'none' { 2 } default { 0 } })"
|
||||
"audiocapturemode:i:$(& $b $R.microphone)"
|
||||
"camerastoredirect:s:$(if (Test-True $R.camera) { '*' } else { '' })"
|
||||
'authentication level:i:2'
|
||||
'prompt for credentials:i:0'
|
||||
'promptcredentialonce:i:1'
|
||||
'enablecredsspsupport:i:1'
|
||||
'autoreconnection enabled:i:1'
|
||||
)
|
||||
if ($R.user) { $l += "username:s:$($R.user)" }
|
||||
if ($R.gateway) {
|
||||
$l += "gatewayhostname:s:$($R.gateway)", 'gatewayusagemethod:i:1', 'gatewaycredentialssource:i:4', 'gatewayprofileusagemethod:i:1', 'gatewaybrokeringtype:i:0'
|
||||
} else { $l += 'gatewayusagemethod:i:4' }
|
||||
if ($R.remoteApp) {
|
||||
$l += 'remoteapplicationmode:i:1', "remoteapplicationprogram:s:||$($R.remoteApp)", "alternate shell:s:||$($R.remoteApp)",
|
||||
"remoteapplicationname:s:$(if ($R.remoteAppName) { $R.remoteAppName } else { $R.remoteApp })", 'disableremoteappcapscheck:i:1'
|
||||
}
|
||||
if (Test-True $R.admin) { $l += 'administrative session:i:1' }
|
||||
if ($R.extra) { $l += @($R.extra -split "`r?`n" | Where-Object { $_ -match '^[^:]+:[isb]:' }) }
|
||||
return ($l -join "`r`n") + "`r`n"
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dateien / Uploads / Blaupausen --------------------------------------------
|
||||
|
||||
$script:UploadTypes = @{
|
||||
installers = '.exe', '.msi', '.msix', '.msixbundle', '.appx', '.appxbundle', '.ps1', '.cmd', '.bat'
|
||||
icons = '.ico', '.exe', '.dll'
|
||||
rdp = '.rdp'
|
||||
}
|
||||
|
||||
function Resolve-UploadTarget {
|
||||
param([string]$Kind, [string]$Name)
|
||||
if (-not $script:UploadTypes.ContainsKey("$Kind")) { throw "Unbekannter Upload-Typ: $Kind" }
|
||||
$n = ([IO.Path]::GetFileName("$Name") -replace '[^\w\-\.\(\)\+ ]', '_').Trim()
|
||||
$ext = [IO.Path]::GetExtension($n).ToLower()
|
||||
if (-not $n -or $ext -notin $script:UploadTypes[$Kind]) { throw "Dateityp '$ext' ist fuer $Kind nicht erlaubt ($($script:UploadTypes[$Kind] -join ', '))" }
|
||||
return @((Join-Path $global:KdsRoot $Kind), $n)
|
||||
}
|
||||
|
||||
function Get-InstallerMetaFile { Join-Path $global:KdsRoot 'installers\installers.json' }
|
||||
|
||||
function Get-InstallerMeta {
|
||||
$f = Get-InstallerMetaFile
|
||||
if (Test-Path $f) { return @([IO.File]::ReadAllText($f) | ConvertFrom-Json | ForEach-Object { $_ }) }
|
||||
return @()
|
||||
}
|
||||
|
||||
function Set-InstallerMeta {
|
||||
# Name + Silent-Parameter je Installer merken (installers\installers.json)
|
||||
param($M)
|
||||
$list = @(Get-InstallerMeta | Where-Object { $_.file -ne $M.file })
|
||||
if (-not $M.remove) { $list += [pscustomobject]@{ file = $M.file; name = $M.name; args = $M.args } }
|
||||
New-Item (Split-Path (Get-InstallerMetaFile)) -ItemType Directory -Force | Out-Null
|
||||
[IO.File]::WriteAllText((Get-InstallerMetaFile), (ConvertTo-Json -InputObject @($list) -Depth 3), (New-Object Text.UTF8Encoding($false)))
|
||||
}
|
||||
|
||||
function Get-LocalInstallers {
|
||||
$dir = Join-Path $global:KdsRoot 'installers'
|
||||
$meta = Get-InstallerMeta
|
||||
@(Get-ChildItem $dir -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Extension.ToLower() -in $script:UploadTypes.installers } | ForEach-Object {
|
||||
$rel = $_.FullName.Substring($global:KdsRoot.Length + 1)
|
||||
$m = $meta | Where-Object file -eq $rel | Select-Object -First 1
|
||||
[pscustomobject]@{
|
||||
file = $rel
|
||||
name = if ($m.name) { [string]$m.name } else { $_.BaseName }
|
||||
args = if ($m) { [string]$m.args } else { '' }
|
||||
sizeMB = [math]::Round($_.Length / 1MB, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function Get-BlueprintPath {
|
||||
param([string]$Id)
|
||||
$safe = ($Id -replace '[^\w\-\. ]', '_').Trim(' .')
|
||||
if (-not $safe) { throw 'Ungueltiger Name' }
|
||||
return (Join-Path $global:KdsRoot "blueprints\$safe.json")
|
||||
}
|
||||
|
||||
function Get-Blueprints {
|
||||
@(Get-ChildItem (Join-Path $global:KdsRoot 'blueprints') -Filter *.json -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
$f = $_
|
||||
try {
|
||||
$j = [IO.File]::ReadAllText($f.FullName) | ConvertFrom-Json
|
||||
[pscustomobject]@{
|
||||
id = $f.BaseName
|
||||
name = if ($j.name) { [string]$j.name } else { $f.BaseName }
|
||||
customer = [string]$j.customer
|
||||
description = [string]$j.description
|
||||
apps = @($j.apps).Where({ $_ }).Count
|
||||
shortcuts = @($j.shortcuts).Where({ $_ }).Count
|
||||
office = [string]$j.office.product
|
||||
steps = @($j.steps)
|
||||
updated = $f.LastWriteTime.ToString('dd.MM.yyyy HH:mm')
|
||||
}
|
||||
} catch { Write-Log "Blaupause $($f.Name) fehlerhaft: $_" 'WARN' }
|
||||
})
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region System / Sicherheit -----------------------------------------------------
|
||||
@@ -753,6 +894,150 @@ function Invoke-VendorDriverUpdate {
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bloatware ---------------------------------------------------------------
|
||||
|
||||
function Get-UninstallEntries {
|
||||
$keys = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*', 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
||||
Get-ItemProperty $keys -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -and -not $_.SystemComponent -and -not $_.ParentKeyName }
|
||||
}
|
||||
|
||||
function Get-BloatwareInventory {
|
||||
# Liefert alle auf diesem Geraet gefundenen Bloatware-Kandidaten
|
||||
$cat = [IO.File]::ReadAllText((Join-Path $global:KdsRoot 'config\bloatware.json')) | ConvertFrom-Json
|
||||
$items = New-Object System.Collections.ArrayList
|
||||
|
||||
# 1) Store-/Appx-Apps (installiert fuer irgendeinen Benutzer oder provisioniert fuer neue Benutzer)
|
||||
$installed = @(Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue | Where-Object { -not $_.NonRemovable })
|
||||
$provisioned = @(Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue)
|
||||
foreach ($e in $cat.appx) {
|
||||
$names = @($installed | Where-Object Name -like $e.pattern | ForEach-Object Name) + @($provisioned | Where-Object DisplayName -like $e.pattern | ForEach-Object DisplayName)
|
||||
foreach ($n in ($names | Sort-Object -Unique)) {
|
||||
if ($items | Where-Object id -eq "appx:$n") { continue }
|
||||
[void]$items.Add([pscustomobject]@{
|
||||
id = "appx:$n"; kind = 'appx'; name = $(if ($e.pattern -notmatch '\*') { $e.name } else { "$($e.name) ($n)" })
|
||||
detail = $n; category = $e.category; recommended = [bool]$e.recommended
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
# 2) Klassische Programme + vorinstallierte Office-Versionen (Click-to-Run)
|
||||
foreach ($u in Get-UninstallEntries) {
|
||||
$dn = [string]$u.DisplayName
|
||||
if ($u.UninstallString -match 'OfficeClickToRun\.exe') {
|
||||
# Consumer-Vorinstallationen (Home/Personal/OneNote Free) empfehlen, Business-Versionen nur anzeigen
|
||||
$consumer = $u.UninstallString -match 'productstoremove=(O365HomePrem|O365Personal|HomeStudent|HomeBusiness|Personal|OneNoteFree|Professional)Retail'
|
||||
[void]$items.Add([pscustomobject]@{
|
||||
id = "arp:$dn"; kind = 'win32'; name = $dn; detail = $(if ($u.UninstallString -match 'productstoremove=([^ ]+)') { $Matches[1] } else { 'Click-to-Run' })
|
||||
category = 'Office / OneNote vorinstalliert'; recommended = $consumer
|
||||
})
|
||||
continue
|
||||
}
|
||||
if ($dn -match '^Microsoft OneDrive') { continue } # eigener Eintrag
|
||||
$hit = $cat.win32 | Where-Object { $dn -match $_.pattern } | Select-Object -First 1
|
||||
if ($hit) {
|
||||
[void]$items.Add([pscustomobject]@{
|
||||
id = "arp:$dn"; kind = 'win32'; name = $dn; detail = "$($u.Publisher) $($u.DisplayVersion)".Trim()
|
||||
category = $hit.category; recommended = [bool]$hit.recommended
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
# 3) OneDrive (systemweit + Autostart fuer neue Benutzer)
|
||||
if ((Get-OneDriveSetups) -or (Get-UninstallEntries | Where-Object DisplayName -match '^Microsoft OneDrive')) {
|
||||
[void]$items.Add([pscustomobject]@{
|
||||
id = 'onedrive'; kind = 'onedrive'; name = 'Microsoft OneDrive'; detail = 'Deinstallation + keine Einrichtung fuer neue Benutzer'
|
||||
category = 'Office / OneNote vorinstalliert'; recommended = $false
|
||||
})
|
||||
}
|
||||
return @($items)
|
||||
}
|
||||
|
||||
function Get-OneDriveSetups {
|
||||
@("$env:SystemRoot\System32\OneDriveSetup.exe", "$env:SystemRoot\SysWOW64\OneDriveSetup.exe") +
|
||||
@(Get-ChildItem "$env:ProgramFiles\Microsoft OneDrive\*\OneDriveSetup.exe", "${env:ProgramFiles(x86)}\Microsoft OneDrive\*\OneDriveSetup.exe" -ErrorAction SilentlyContinue | ForEach-Object FullName) |
|
||||
Where-Object { Test-Path $_ }
|
||||
}
|
||||
|
||||
function Remove-OneDrive {
|
||||
Get-Process OneDrive -ErrorAction SilentlyContinue | Stop-Process -Force
|
||||
foreach ($s in Get-OneDriveSetups) {
|
||||
$a = if ($s -like "$env:ProgramFiles*" -or $s -like "${env:ProgramFiles(x86)}*") { '/uninstall /allusers' } else { '/uninstall' }
|
||||
Write-Log " $s $a"
|
||||
Start-Process $s -ArgumentList $a -Wait -WindowStyle Hidden
|
||||
}
|
||||
# Automatische Einrichtung fuer neue Benutzerprofile verhindern
|
||||
reg load HKU\KdsDefault "$env:SystemDrive\Users\Default\NTUSER.DAT" 2>$null | Out-Null
|
||||
reg delete 'HKU\KdsDefault\Software\Microsoft\Windows\CurrentVersion\Run' /v OneDriveSetup /f 2>$null | Out-Null
|
||||
[gc]::Collect(); reg unload HKU\KdsDefault 2>$null | Out-Null
|
||||
Remove-Item "$env:PUBLIC\Desktop\OneDrive.lnk", "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk" -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
function Remove-Win32App {
|
||||
param([string]$DisplayName)
|
||||
$u = Get-UninstallEntries | Where-Object DisplayName -eq $DisplayName | Select-Object -First 1
|
||||
if (-not $u) { Write-Log ' nicht (mehr) installiert'; return 0 }
|
||||
$us = [string]$u.UninstallString
|
||||
if ($us -match 'OfficeClickToRun\.exe') {
|
||||
# ARP-String von Click-to-Run + DisplayLevel=False = stille Deinstallation
|
||||
if ($us -match '^"([^"]+)"\s*(.*)$') { $exe = $Matches[1]; $rest = $Matches[2] }
|
||||
else { $exe, $rest = $us -split ' ', 2 }
|
||||
return (Start-Process $exe -ArgumentList "$rest DisplayLevel=False" -Wait -PassThru).ExitCode
|
||||
}
|
||||
if ($us -match 'msiexec' -and $u.PSChildName -match '^\{[0-9A-F\-]+\}$') {
|
||||
return (Start-Process msiexec.exe -ArgumentList "/x $($u.PSChildName) /qn /norestart" -Wait -PassThru).ExitCode
|
||||
}
|
||||
if ($u.QuietUninstallString) {
|
||||
return (Start-Process cmd.exe -ArgumentList "/c `"$($u.QuietUninstallString)`"" -Wait -PassThru -WindowStyle Hidden).ExitCode
|
||||
}
|
||||
# Fallback: winget kennt fuer viele ARP-Eintraege den passenden Silent-Schalter
|
||||
if (Get-WingetPath) {
|
||||
$arch = if ($u.PSPath -match 'WOW6432Node') { 'X86' } else { 'X64' }
|
||||
$code = Invoke-Winget @('uninstall', '--id', "ARP\Machine\$arch\$($u.PSChildName)", '--exact', '--silent', '--force', '--accept-source-agreements', '--disable-interactivity')
|
||||
if ($code -eq 0) { return 0 }
|
||||
}
|
||||
Write-Log ' Kein stiller Deinstaller bekannt - starte Standard-Deinstallation (evtl. mit Dialog)' 'WARN'
|
||||
return (Start-Process cmd.exe -ArgumentList "/c `"$us`"" -Wait -PassThru).ExitCode
|
||||
}
|
||||
|
||||
function Remove-Bloatware {
|
||||
param($Data)
|
||||
$cfg = $Data.bloatware
|
||||
Write-Log 'Ermittle installierte Bloatware ...'
|
||||
$inv = Get-BloatwareInventory
|
||||
$ids = @($cfg.ids)
|
||||
$keep = @($cfg.keep)
|
||||
$sel = @($inv | Where-Object { ($_.id -in $ids) -or ((Test-True $cfg.recommended) -and $_.recommended -and $_.id -notin $keep) })
|
||||
if (-not $sel.Count) { Write-Log 'Nichts zu entfernen.' 'OK'; return }
|
||||
Write-Log "$($sel.Count) Eintraege werden entfernt"
|
||||
$fail = 0
|
||||
foreach ($it in $sel) {
|
||||
Write-Log "- $($it.name) [$($it.category)]"
|
||||
try {
|
||||
switch ($it.kind) {
|
||||
'appx' {
|
||||
$n = $it.detail
|
||||
Get-AppxPackage -AllUsers -Name $n -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
try { Remove-AppxPackage -Package $_.PackageFullName -AllUsers -ErrorAction Stop } catch { Write-Log " $($_.Exception.Message)" 'WARN' }
|
||||
}
|
||||
Get-AppxProvisionedPackage -Online | Where-Object DisplayName -eq $n | ForEach-Object {
|
||||
Remove-AppxProvisionedPackage -Online -PackageName $_.PackageName -AllUsers -ErrorAction SilentlyContinue | Out-Null
|
||||
}
|
||||
Write-Log ' entfernt' 'OK'
|
||||
}
|
||||
'win32' {
|
||||
$code = Remove-Win32App ($it.id -replace '^arp:', '')
|
||||
if ($code -in 0, 3010, 1605, 1641) { Write-Log " entfernt ($code)" 'OK' } else { throw "ExitCode $code" }
|
||||
}
|
||||
'onedrive' { Remove-OneDrive; Write-Log ' OneDrive entfernt' 'OK' }
|
||||
}
|
||||
} catch { $fail++; Write-Log " Fehler: $_" 'ERROR' }
|
||||
}
|
||||
Write-Log "Bloatware: $($sel.Count - $fail) entfernt, $fail Fehler" $(if ($fail) { 'WARN' } else { 'OK' })
|
||||
if ($sel | Where-Object name -match 'McAfee') { Write-Log 'Tipp: McAfee-Reste ggf. mit dem McAfee Consumer Product Removal Tool (MCPR) entfernen.' 'WARN' }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Gesamtprofil ------------------------------------------------------------
|
||||
|
||||
function Invoke-FullProfile {
|
||||
@@ -765,6 +1050,7 @@ function Invoke-FullProfile {
|
||||
try { & $block } catch { Write-Log "$title fehlgeschlagen: $_" 'ERROR' }
|
||||
}
|
||||
if ('system' -in $steps) { & $run 'System' { Set-SystemConfig $Data } }
|
||||
if ('bloatware' -in $steps) { & $run 'Bloatware entfernen' { Remove-Bloatware $Data } }
|
||||
if ('security' -in $steps) { & $run 'Sicherheit' { Set-SecurityConfig $Data } }
|
||||
if ('power' -in $steps) { & $run 'Energie' { Set-PowerConfig $Data } }
|
||||
if ('apps' -in $steps) { & $run 'Programme' { Install-Apps $Data } }
|
||||
|
||||
Reference in New Issue
Block a user