PSDependScripts/WindowsRSAT.ps1
|
<#
.SYNOPSIS 'Install a WindowsRSAT PowerShell module using Add-WindowsCapability or Install-WindowsFeature, depending on OS' .DESCRIPTION Installs a RSAT Module in Windows. The Install action requires an elevated (administrator) session, on both Workstation (Add-WindowsCapability) and Server (Install-WindowsFeature). The Test action does not require elevation. If the module is already present, all actions short-circuit and succeed without elevation. Relevant Dependency metadata: Name: The name for the module to install .PARAMETER PSDependAction Test, Install, or Import the module. Defaults to Install Test: Return true or false on whether the dependency is in place Install: Install the dependency Import: Import the dependency .EXAMPLE @{ ActiveDirectory = @{ DependencyType = 'WindowsRSAT' Name = 'ActiveDirectory' } } #> [cmdletbinding()] param( [PSTypeName('PSDepend.Dependency')] [psobject[]]$Dependency, [ValidateSet('Test', 'Install', 'Import')] [string[]]$PSDependAction = @('Install') ) $RSAT_MODULE_MAP = @{ 'ActiveDirectory' = @{ 'WindowsFeature' = 'RSAT-AD-Powershell' 'WindowsCapability' = 'Rsat.ActiveDirectory.DS-LDS.Tools' } 'ADDSDeployment' = @{ 'WindowsFeature' = 'RSAT-AD-Powershell' 'WindowsCapability' = 'Rsat.ActiveDirectory.DS-LDS.Tools' } 'ADCSAdministration' = @{ 'WindowsFeature' = 'RSAT-ADCS-Mgmt' 'WindowsCapability' = 'Rsat.CertificateServices.Tools' } 'ADCSDeployment' = @{ 'WindowsFeature' = 'RSAT-ADCS-Mgmt' 'WindowsCapability' = 'Rsat.CertificateServices.Tools' } 'ADRMS' = @{ 'WindowsFeature' = 'RSAT-ADRMS' #'WindowsCapability' = 'Rsat.CertificateServices.Tools' } 'ADRMSAdmin' = @{ 'WindowsFeature' = 'RSAT-ADRMS' #'WindowsCapability' = 'Rsat.CertificateServices.Tools' } 'BitLocker' = @{ 'WindowsFeature' = 'RSAT-Feature-Tools-BitLocker-RemoteAdminTool' 'WindowsCapability' = 'Rsat.BitLocker.Recovery.Tools' } 'DFSN' = @{ 'WindowsFeature' = 'RSAT-DFS-Mgmt-Con' #'WindowsCapability' = 'Rsat.BitLocker.Recovery.Tools' } 'DFSR' = @{ 'WindowsFeature' = 'RSAT-DFS-Mgmt-Con' #'WindowsCapability' = 'Rsat.BitLocker.Recovery.Tools' } 'DHCP' = @{ 'WindowsFeature' = 'RSAT-DHCP' 'WindowsCapability' = 'Rsat.DHCP.Tools' } 'DNSClient' = @{ 'WindowsFeature' = 'RSAT-DNS-Server' 'WindowsCapability' = 'Rsat.Dns.Tools' } 'DNSServer' = @{ 'WindowsFeature' = 'RSAT-DNS-Server' 'WindowsCapability' = 'Rsat.Dns.Tools' } 'FailoverClusters' = @{ 'WindowsFeature' = 'RSAT-Clustering-PowerShell' 'WindowsCapability' = 'Rsat.FailoverCluster.Management.Tools' } 'FileServerResourceManager' = @{ 'WindowsFeature' = 'RSAT-FSRM-Mgmt' #'WindowsCapability' = 'Rsat.FileServices.Tools' } 'GroupPolicy' = @{ 'WindowsFeature' = 'GPMC' 'WindowsCapability' = 'Rsat.GroupPolicy.Management.Tools' } 'Hyper-V' = @{ 'WindowsFeature' = 'RSAT-Hyper-V-Tools' #'WindowsCapability' = 'Rsat.GroupPolicy.Management.Tools' } 'IISAdministration' = @{ 'WindowsFeature' = 'web-mgmt-console' #'WindowsCapability' = 'Rsat.GroupPolicy.Management.Tools' } 'RemoteAccess' = @{ 'WindowsFeature' = 'RSAT-RemoteAccess-Powershell' 'WindowsCapability' = 'Rsat.RemoteAccess.Management.Tools' } 'VAMT' = @{ 'WindowsFeature' = 'RSAT-VA-Tools' 'WindowsCapability' = 'Rsat.VolumeActivation.Tools' } } # Extract data from Dependency $ModuleName = $Dependency.Name if (-not $ModuleName) { $ModuleName = $Dependency.DependencyName } if (Get-Module -ListAvailable -Name $ModuleName -ErrorAction SilentlyContinue) { Write-Verbose "Found existing module [$ModuleName]" if ($PSDependAction -contains 'Test') { return $True } return $null } #No dependency found, return false if we're testing alone... if ( $PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) { return $False } if ($PSDependAction -contains 'Install') { if (-not (Test-Administrator)) { throw "Installing RSAT module '$ModuleName' requires an elevated session. Re-run from a PowerShell started with 'Run as administrator'." } #Server $Type = 'WindowsFeature' if ((Get-CimInstance -ClassName Win32_OperatingSystem).ProductType -eq 1) { # Workstation $Type = 'WindowsCapability' } if (-not $RSAT_MODULE_MAP.ContainsKey($ModuleName)) { throw "Unknown module '$ModuleName'. No RSAT mapping is defined for it." } $mapping = $RSAT_MODULE_MAP[$ModuleName] if (-not $mapping.ContainsKey($Type) -or [string]::IsNullOrEmpty($mapping[$Type])) { # In the table, but no entry for this OS install path. Most commonly a # module that ships only as a Server feature (e.g. Hyper-V, ADRMS) and # has no equivalent Windows capability on a Workstation. throw "Module '$ModuleName' is not available via $Type on this system (it may be server-only)." } if ($Type -eq 'WindowsFeature') { $null = Install-WindowsFeature -Name $mapping[$Type] } else { # Resolve the exact capability identity (e.g. # 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0') from the stable short # name in the map. DISM does accept the short base name directly, but # that relies on undocumented prefix matching and the version suffix # varies by Windows build -- so look it up and pass the canonical name. $capabilityName = $mapping[$Type] $capability = Get-WindowsCapability -Online -Name "$capabilityName*" | Select-Object -First 1 if (-not $capability) { throw "No Windows capability matching '$capabilityName' was found on this system." } $null = Add-WindowsCapability -Online -Name $capability.Name } } # Conditional import Import-PSDependModule -Name $ModuleName -Action $PSDependAction |