Add DSC configurations for user interface, Windows features, and services; implement app installation and removal scripts
- Created `DSC-UserInterfaceConfiguration.ps1` to manage user interface settings via registry changes. - Developed `DSC-WindowsFeatures.ps1` to install OpenSSH Client and enable NFS Client features. - Implemented `DSC-WindowsServices.ps1` to ensure Terminal Services are running and set to automatic startup. - Added `PS-InstallApps.ps1` to manage app installations and remove the msstore source if it exists. - Created `PS-RemoveApps.ps1` to remove unwanted apps, provisioned packages, and handle Office applications via winget.
This commit is contained in:
363
1_Install.ps1
363
1_Install.ps1
@@ -1,3 +1,5 @@
|
||||
# === Admin Check ===
|
||||
|
||||
# set-executionpolicy unrestricted
|
||||
|
||||
# Check if running as administrator
|
||||
@@ -21,243 +23,158 @@ if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdent
|
||||
}
|
||||
|
||||
Write-Host "Running with administrator privileges." -ForegroundColor Green
|
||||
|
||||
$uid = $Env:UserName # Get current username for use in paths
|
||||
Write-Host "Current user: $uid" -ForegroundColor Green
|
||||
|
||||
reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve
|
||||
# === PREREQUISITE CHECKS ===
|
||||
|
||||
# Check and install OpenSSH Client if not already installed
|
||||
$sshCapability = Get-WindowsCapability -Online | Where-Object { $_.Name -like "OpenSSH.Client*" }
|
||||
if ($sshCapability.State -ne "Installed") {
|
||||
Write-Host "Installing OpenSSH Client..." -ForegroundColor Yellow
|
||||
Add-WindowsCapability -Online -Name 'OpenSSH.Client~~~~0.0.1.0'
|
||||
} else {
|
||||
Write-Host "OpenSSH Client is already installed." -ForegroundColor Green
|
||||
# Check if winget is installed
|
||||
Write-Host "Checking winget installation..." -ForegroundColor Yellow
|
||||
try {
|
||||
$wingetVersion = winget --version
|
||||
Write-Host "winget is installed: $wingetVersion" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "winget is not installed or not accessible. Please install winget first."
|
||||
Write-Host "You can install winget from the Microsoft Store (App Installer) or GitHub." -ForegroundColor Red
|
||||
Write-Host "GitHub: https://github.com/microsoft/winget-cli/releases" -ForegroundColor Cyan
|
||||
pause
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check and enable NFS features if not already enabled
|
||||
$nfsClientOnly = Get-WindowsOptionalFeature -Online -FeatureName "ServicesForNFS-ClientOnly"
|
||||
$nfsInfrastructure = Get-WindowsOptionalFeature -Online -FeatureName "ClientForNFS-Infrastructure"
|
||||
|
||||
if ($nfsClientOnly.State -ne "Enabled" -or $nfsInfrastructure.State -ne "Enabled") {
|
||||
Write-Host "Enabling NFS Client features..." -ForegroundColor Yellow
|
||||
Enable-WindowsOptionalFeature -FeatureName ServicesForNFS-ClientOnly, ClientForNFS-Infrastructure -Online -NoRestart
|
||||
} else {
|
||||
Write-Host "NFS Client features are already enabled." -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Check if msstore source exists before trying to remove it
|
||||
$msstoreSource = winget source list | Select-String "msstore"
|
||||
if ($msstoreSource) {
|
||||
Write-Host "Removing msstore source..." -ForegroundColor Yellow
|
||||
winget source remove msstore
|
||||
} else {
|
||||
Write-Host "msstore source is already removed or not found." -ForegroundColor Green
|
||||
}
|
||||
|
||||
winget import -i .\winget.json
|
||||
winget pin add Discord.Discord
|
||||
|
||||
#RDP Magic
|
||||
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
|
||||
Set-Service -Name TermService -StartupType Automatic
|
||||
Start-Service -Name TermService
|
||||
|
||||
|
||||
# Remove unwanted Windows apps
|
||||
Write-Host "Checking and removing unwanted Windows apps..." -ForegroundColor Yellow
|
||||
|
||||
$appsToRemove = @(
|
||||
"Microsoft.MicrosoftSolitaireCollection", # Solitaire
|
||||
"Microsoft.MicrosoftOfficeHub", # Office preinstalls
|
||||
"Microsoft.Windows.Photos", # Photos
|
||||
"Microsoft.Copilot", # Copilot
|
||||
"Microsoft.BingNews", # News
|
||||
"Microsoft.BingWeather", # Weather
|
||||
"Clipchamp.Clipchamp", # Clipchamp
|
||||
"MSTeams", # Teams
|
||||
"Microsoft.Todos", # To-Do
|
||||
"Microsoft.WebMediaExtensions", # Media extensions
|
||||
"Microsoft.WindowsMediaPlayer", # Legacy Media Player (if exists)
|
||||
"Microsoft.ZuneMusic", # Music app
|
||||
"Microsoft.ZuneVideo", # Movies & TV app (if exists)
|
||||
"Microsoft.Media.Player", # New Windows Media Player (if exists)
|
||||
"Microsoft.OutlookForWindows", # New Outlook app
|
||||
"Microsoft.Office.OneNote", # OneNote (AppX version)
|
||||
"Microsoft.MicrosoftOfficeHub", # Office Hub
|
||||
"7EX16E2Z690YF.LinkedInforWindows", # LinkedIn (actual package name)
|
||||
"LinkedIn.LinkedIn", # LinkedIn (alternative name)
|
||||
"Microsoft.OneDrive" # OneDrive (if exists as app package)
|
||||
)
|
||||
|
||||
foreach ($app in $appsToRemove) {
|
||||
$installedApp = Get-AppxPackage -Name $app -ErrorAction SilentlyContinue
|
||||
if ($installedApp) {
|
||||
try {
|
||||
Write-Host "Removing $app..." -ForegroundColor Red
|
||||
Remove-AppxPackage -Package $installedApp.PackageFullName -ErrorAction Stop
|
||||
Write-Host "Successfully removed $app" -ForegroundColor Green
|
||||
# Install Microsoft DSC
|
||||
Write-Host "Installing Microsoft DSC..." -ForegroundColor Yellow
|
||||
try {
|
||||
# Check if already installed
|
||||
$dscInstalled = winget list --id Microsoft.DSC --exact 2>$null
|
||||
if ($LASTEXITCODE -eq 0 -and $dscInstalled -match "Microsoft.DSC") {
|
||||
Write-Host "Microsoft DSC is already installed." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Installing Microsoft DSC via winget..." -ForegroundColor Yellow
|
||||
winget install Microsoft.DSC --silent --accept-source-agreements --accept-package-agreements
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "Microsoft DSC installed successfully." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "Failed to install Microsoft DSC. DSC configurations may not work properly."
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to remove $app`: $_"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "$app is not installed or already removed" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
|
||||
# Also remove for all users (provisioned packages)
|
||||
Write-Host "Checking and removing provisioned app packages for all users..." -ForegroundColor Yellow
|
||||
|
||||
foreach ($app in $appsToRemove) {
|
||||
$provisionedApp = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq $app }
|
||||
if ($provisionedApp) {
|
||||
try {
|
||||
Write-Host "Removing provisioned package for $app..." -ForegroundColor Red
|
||||
Remove-AppxProvisionedPackage -Online -PackageName $provisionedApp.PackageName -ErrorAction Stop
|
||||
Write-Host "Successfully removed provisioned package for $app" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to remove provisioned package for $app`: $_"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "Provisioned package for $app is not found or already removed" -ForegroundColor Gray
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to check/install Microsoft DSC: $_"
|
||||
}
|
||||
|
||||
Write-Host "App removal process completed." -ForegroundColor Green
|
||||
|
||||
# Remove unwanted Office applications via winget
|
||||
Write-Host "Checking and removing unwanted Office applications..." -ForegroundColor Yellow
|
||||
|
||||
# Cache winget list to avoid multiple calls (it's slow)
|
||||
Write-Host "Getting installed applications list (this may take a moment)..." -ForegroundColor Gray
|
||||
$wingetList = winget list | Out-String
|
||||
|
||||
$officeAppsToRemove = @(
|
||||
"Microsoft.OneDrive", # OneDrive (if exists as winget package)
|
||||
"OneNoteFreeRetail - en-us", # Microsoft OneNote - en-us
|
||||
"OneNoteFreeRetail - es-es", # Microsoft OneNote - es-es
|
||||
"OneNoteFreeRetail - fr-fr", # Microsoft OneNote - fr-fr
|
||||
"OneNoteFreeRetail - pt-br", # Microsoft OneNote - pt-br
|
||||
"O365HomePremRetail - en-us", # Microsoft 365 - en-us
|
||||
"O365HomePremRetail - es-es", # Microsoft 365 - es-es
|
||||
"O365HomePremRetail - fr-fr", # Microsoft 365 - fr-fr
|
||||
"O365HomePremRetail - pt-br", # Microsoft 365 - pt-br
|
||||
"Microsoft.WindowsFeedbackHub_8wekyb3d8bbwe", # Feedback Hub
|
||||
"Microsoft.BingSearch_8wekyb3d8bbwe", # Bing Search (if exists)
|
||||
"Microsoft.OutlookForWindows_8wekyb3d8bbwe", # New Outlook (if exists)
|
||||
"MicrosoftCorporationII.MicrosoftFamily_8wekyb3d8bbwe" # Microsoft Family (if exists)
|
||||
)
|
||||
|
||||
foreach ($app in $officeAppsToRemove) {
|
||||
# Check if the app is installed using the cached winget list
|
||||
$appFound = $wingetList -match [regex]::Escape($app)
|
||||
|
||||
if ($appFound) {
|
||||
try {
|
||||
Write-Host "Removing $app..." -ForegroundColor Red
|
||||
winget uninstall "$app" --silent --accept-source-agreements
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "Successfully removed $app" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "winget uninstall returned exit code $LASTEXITCODE for $app"
|
||||
}
|
||||
# Configure WinRM service for DSC
|
||||
Write-Host "Configuring WinRM service..." -ForegroundColor Yellow
|
||||
try {
|
||||
# Start WinRM service
|
||||
$winrmService = Get-Service -Name WinRM -ErrorAction SilentlyContinue
|
||||
if ($winrmService) {
|
||||
if ($winrmService.Status -ne "Running") {
|
||||
Write-Host "Starting WinRM service..." -ForegroundColor Yellow
|
||||
Start-Service WinRM
|
||||
Write-Host "WinRM service started." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "WinRM service is already running." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to remove $app`: $_"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "$app is not installed or already removed" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Office application removal process completed." -ForegroundColor Green
|
||||
|
||||
# Remove Edge Progressive Web Apps (PWAs) like LinkedIn
|
||||
Write-Host "Checking and removing Edge Progressive Web Apps..." -ForegroundColor Yellow
|
||||
|
||||
$edgePWAPath = "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Web Applications"
|
||||
if (Test-Path $edgePWAPath) {
|
||||
try {
|
||||
$pwaFolders = Get-ChildItem -Path $edgePWAPath -Directory -ErrorAction SilentlyContinue
|
||||
foreach ($folder in $pwaFolders) {
|
||||
$manifestPath = Join-Path $folder.FullName "Manifest"
|
||||
if (Test-Path $manifestPath) {
|
||||
$manifestContent = Get-Content $manifestPath -Raw -ErrorAction SilentlyContinue
|
||||
if ($manifestContent -match "linkedin" -or $manifestContent -match "LinkedIn") {
|
||||
Write-Host "Found LinkedIn PWA, removing folder: $($folder.Name)" -ForegroundColor Red
|
||||
Remove-Item -Path $folder.FullName -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "Removed LinkedIn PWA" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to check Edge PWAs: $_"
|
||||
}
|
||||
} else {
|
||||
Write-Host "Edge PWA directory not found" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host "Edge PWA removal process completed." -ForegroundColor Green
|
||||
|
||||
# Font Install
|
||||
Write-Host "Checking and installing fonts..." -ForegroundColor Yellow
|
||||
$fontSourceFolder = ".\Fonts"
|
||||
$fontDestFolder = "C:\Windows\Fonts"
|
||||
$regPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts"
|
||||
|
||||
# Process each TTF file
|
||||
Get-ChildItem -Path $fontSourceFolder -Filter "*.ttf" | ForEach-Object {
|
||||
$fontFile = $_.FullName
|
||||
$fontName = $_.BaseName
|
||||
$destFile = Join-Path -Path $fontDestFolder -ChildPath $_.Name
|
||||
$regName = "$fontName (TrueType)"
|
||||
|
||||
# Check if font file already exists in destination
|
||||
$fontExists = Test-Path -Path $destFile
|
||||
|
||||
# Check if registry entry already exists
|
||||
$regExists = $false
|
||||
try {
|
||||
$regValue = Get-ItemProperty -Path $regPath -Name $regName -ErrorAction SilentlyContinue
|
||||
$regExists = ($regValue -ne $null)
|
||||
}
|
||||
catch {
|
||||
$regExists = $false
|
||||
}
|
||||
|
||||
# Only install if font file doesn't exist or registry entry is missing
|
||||
if (-not $fontExists -or -not $regExists) {
|
||||
try {
|
||||
Write-Host "Installing font: $($_.Name)..." -ForegroundColor Yellow
|
||||
|
||||
# Copy font file if it doesn't exist
|
||||
if (-not $fontExists) {
|
||||
Copy-Item -Path $fontFile -Destination $destFile -Force
|
||||
Write-Host " - Copied font file to Windows\Fonts" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " - Font file already exists, skipping copy" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# Add/update registry entry if it doesn't exist
|
||||
if (-not $regExists) {
|
||||
New-ItemProperty -Path $regPath -Name $regName -Value $_.Name -PropertyType String -Force | Out-Null
|
||||
Write-Host " - Added registry entry" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " - Registry entry already exists, skipping" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to install font $($_.Name): $_"
|
||||
|
||||
# Set to automatic startup
|
||||
if ($winrmService.StartType -ne "Automatic") {
|
||||
Write-Host "Setting WinRM service to automatic startup..." -ForegroundColor Yellow
|
||||
Set-Service WinRM -StartupType Automatic
|
||||
Write-Host "WinRM service set to automatic startup." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "WinRM service is already set to automatic startup." -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Host "Font $($_.Name) is already installed (file and registry entry exist)" -ForegroundColor Green
|
||||
Write-Warning "WinRM service not found. DSC configurations may not work properly."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to configure WinRM service: $_"
|
||||
}
|
||||
|
||||
# Clear any pending DSC configurations
|
||||
Write-Host "Checking and clearing any pending DSC configurations..." -ForegroundColor Yellow
|
||||
try {
|
||||
# Force stop any running DSC operations
|
||||
Write-Host "Stopping any active DSC operations..." -ForegroundColor Yellow
|
||||
Stop-DscConfiguration -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
# Check DSC status
|
||||
$dscStatus = Get-DscLocalConfigurationManager -ErrorAction SilentlyContinue
|
||||
if ($dscStatus) {
|
||||
Write-Host "Current DSC LCM State: $($dscStatus.LCMState)" -ForegroundColor Cyan
|
||||
|
||||
# If still not idle, try more aggressive cleanup
|
||||
if ($dscStatus.LCMState -ne "Idle") {
|
||||
Write-Host "Performing aggressive DSC cleanup..." -ForegroundColor Yellow
|
||||
|
||||
# Try to cancel any pending operations
|
||||
Stop-DscConfiguration -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
|
||||
# Remove any pending.mof files that might be causing issues
|
||||
$pendingMof = "$env:SystemRoot\System32\Configuration\pending.mof"
|
||||
$currentMof = "$env:SystemRoot\System32\Configuration\current.mof"
|
||||
|
||||
if (Test-Path $pendingMof) {
|
||||
Remove-Item $pendingMof -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "Removed pending.mof file." -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Re-check status
|
||||
Start-Sleep -Seconds 2
|
||||
$dscStatus = Get-DscLocalConfigurationManager -ErrorAction SilentlyContinue
|
||||
Write-Host "Final DSC LCM State: $($dscStatus.LCMState)" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
if ($dscStatus.LCMState -eq "Idle") {
|
||||
Write-Host "DSC is ready for new configurations." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "DSC may still be in pending state. Will use -Force parameter for configurations."
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to check/clear DSC status: $_"
|
||||
Write-Host "Will proceed with -Force parameter for DSC configurations." -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# === Install Features/Enable Services ===
|
||||
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Write-Host "Running Windows Features DSC configuration..." -ForegroundColor Yellow
|
||||
& "$scriptDir\DSC-WindowsFeatures.ps1"
|
||||
|
||||
Write-Host "Running Windows Services DSC configuration..." -ForegroundColor Yellow
|
||||
& "$scriptDir\DSC-WindowsServices.ps1"
|
||||
|
||||
# === Disable Telemetry ===
|
||||
|
||||
Write-Host "Running Telemetry, Privacy & Security DSC configuration..." -ForegroundColor Yellow
|
||||
& "$scriptDir\DSC-TelemetryPrivacySecurity.ps1"
|
||||
|
||||
# === Remove Apps ===
|
||||
|
||||
Write-Host "Running App Removal script..." -ForegroundColor Yellow
|
||||
& "$scriptDir\PS-RemoveApps.ps1"
|
||||
|
||||
# === Install Apps ===
|
||||
|
||||
Write-Host "Running App Installation script..." -ForegroundColor Yellow
|
||||
& "$scriptDir\PS-InstallApps.ps1"
|
||||
|
||||
# === Configure User Interface ===
|
||||
|
||||
Write-Host "Running User Interface DSC configuration..." -ForegroundColor Yellow
|
||||
& "$scriptDir\DSC-UserInterfaceConfiguration.ps1"
|
||||
|
||||
# === Configure Environment Variables ===
|
||||
|
||||
Write-Host "Running Environment Variables DSC configuration..." -ForegroundColor Yellow
|
||||
& "$scriptDir\DSC-EnvironmentVariables.ps1"
|
||||
|
||||
# === File Operations ===
|
||||
Write-Host "Running File Operations DSC configuration..." -ForegroundColor Yellow
|
||||
& "$scriptDir\DSC-FileOperations.ps1"
|
||||
|
||||
Reference in New Issue
Block a user