function Get-RolesAndFeatures {<#.SYNOPSISGets a list of Features / Roles / Role Services on the target server..DESCRIPTIONThe data returned for each includes name, description, installstate, installed?... Can be called with a FeatureName or FeatureType both of which are optional..EXAMPLE./GetFeaturesAndRoles.ps1When called with no parameters, returns data for all roles, features and role services available on the server.EXAMPLE./GetFeaturesAndRoles.ps1 -FeatureName 'Web-Server'When called with a FeatureName (e.g. Web-Server) returns details for the given feature if it is available.EXAMPLE./GetFeaturesAndRoles.ps1 -FeatureType 'Role'When called with a FeatureType ('Role', 'Feature' or 'Role Service) returns details for all avilable features of that FeatureType.NOTESThe supported Operating Systems are Window Server 2012, Windows Server 2012R2, Windows Server 2016..ROLEReaders#>param( [Parameter(Mandatory=$False)] [string] $FeatureName = '', [Parameter(Mandatory=$False)] [ValidateSet('Role', 'Role Service', 'Feature', IgnoreCase=$False)] [string] $FeatureType = '')Import-Module ServerManager$result = $nullif ($FeatureName) { $result = Get-WindowsFeature -Name $FeatureName} else { if ($FeatureType) { $result = Get-WindowsFeature | Where-Object { $_.FeatureType -EQ $FeatureType } } else { $result = Get-WindowsFeature }}$result}## [END] Get-RolesAndFeatures ##function Install-RolesAndFeatures {<#.SYNOPSISInstalls a Feature/Role/Role Service on the target server..DESCRIPTIONInstalls a Feature/Role/Role Service on the target server, using Install-WindowsFeature PowerShell cmdlet. Returns a status objectthat contains the following properties:success - true/false depending on if the overall operation Succeededstatus - status messageresult - response from Install-WindowsFeature call.PARAMETER FeatureNameIs a required parameter and is the name of the Role/Feature/Role Service to install.PARAMETER IncludeAllSubFeatureIs an optional switch parameter that is passed as a similar named parameter to Install-WindowsFeature.PARAMETER IncludeManagementToolsIs an optional switch parameter that is passed as a similar named parameter to Install-WindowsFeature.PARAMETER RestartIs an optional switch parameter that is passed as a similar named parameter to Install-WindowsFeature.EXAMPLE./InstallRolesAndFeature.ps1 -FeatureName 'ManagementOData'Installs the feature 'ManagementObject' without subfeature and management tools.EXAMPLE./InstallRolesAndFeature.ps1 -FeatureName 'Web-Server' -IncludeAllSubFeature -IncludeManagementToolsInstalls the role 'Web-Server' with all dependencies and management tools.EXAMPLE./InstallRolesAndFeature.ps1 -FeatureName 'ManagementOData' -RestartInstalls the feature 'ManagementObject' without subfeature and management tools and reboots the server.NOTESThe supported Operating Systems are Window Server 2012, Windows Server 2012R2, Windows Server 2016..ROLEAdministrators#>param( [Parameter(Mandatory=$True)] [string[]] $FeatureName, [Parameter(Mandatory=$False)] [Switch] $IncludeAllSubFeature, [Parameter(Mandatory=$False)] [Switch] $IncludeManagementTools, [Parameter(Mandatory=$False)] [Switch] $Restart, [Parameter(Mandatory=$False)] [Switch] $WhatIf)Import-Module ServerManagerEnum InstallStatus { Failed = 0 Succeeded = 1 NoSuchFeature = 2 AlreadyInstalled = 3 Pending = 4}$result = $Null$status = $Null$success = $False$ErrorActionPreference = "Stop"$feature = Get-WindowsFeature -Name $FeatureNameIf ($feature) { If ($feature.Where({$_.InstallState -eq 'Available'})) { Try { $result = Install-WindowsFeature -Name $FeatureName -IncludeAllSubFeature:$IncludeAllSubFeature -IncludeManagementTools:$IncludeManagementTools -Restart:$Restart -WhatIf:$WhatIf $success = $result -AND $result.Success $status = if ($success) { [InstallStatus]::Succeeded } Else { [InstallStatus]::Failed } } Catch { If ($success -AND $Restart -AND $result.restartNeeded -eq 'Yes') { $status = [InstallStatus]::Pending $error.clear() } Else { Throw } } } Else { $success = $True $status = [InstallStatus]::AlreadyInstalled }} Else { $success = $False $status = [InstallStatus]::NoSuchFeature}@{ 'success' = $success ; 'status' = $status ; 'result' = $result }}## [END] Install-RolesAndFeatures ##function Uninstall-RolesAndFeatures {<#.SYNOPSISUnInstalls a Feature/Role/Role Service on the target server..DESCRIPTIONUnInstalls a Feature/Role/Role Service on the target server, using UnInstall-WindowsFeature PowerShell cmdlet. Returns a status objectthat contains the following properties:success - true/false depending on if the overall operation Succeededstatus - status messageresult - response from UnInstall-WindowsFeature call.PARAMETER FeatureNameIs a required parameter and is the name of the Role/Feature/Role Service to un-install.PARAMETER IncludeManagementToolsIs an optional switch parameter that is passed as a similar named parameter to Install-WindowsFeature.PARAMETER RestartIs an optional switch parameter that is passed as a similar named parameter to Install-WindowsFeature.EXAMPLE./UnInstallRolesAndFeature.ps1 -FeatureName 'ManagementOData'Un-Installs the feature 'ManagementObject'.EXAMPLE./UnInstallRolesAndFeature.ps1 -FeatureName 'Web-Server' -IncludeManagementToolsUn-Installs the role 'Web-Server' and management tools.EXAMPLE./UnInstallRolesAndFeature.ps1 -FeatureName 'ManagementOData' -RestartUn-Installs the feature 'ManagementObject' without management tools and reboots the server.NOTESThe supported Operating Systems are Window Server 2012, Windows Server 2012R2, Windows Server 2016..ROLEAdministrators#>param( [Parameter(Mandatory=$True)] [string[]] $FeatureName, [Parameter(Mandatory=$False)] [Switch] $IncludeManagementTools, [Parameter(Mandatory=$False)] [Switch] $Restart, [Parameter(Mandatory=$False)] [Switch] $WhatIf)Import-Module ServerManagerEnum UnInstallStatus { Failed = 0 Succeeded = 1 NoSuchFeature = 2 NotInstalled = 3 Pending = 4}$result = $Null$status = $Null$success = $False$ErrorActionPreference = "Stop"$feature = Get-WindowsFeature -Name $FeatureNameIf ($feature) { If ($feature.Where({$_.InstallState -eq 'Installed'})) { Try { $result = UnInstall-WindowsFeature -Name $FeatureName -IncludeManagementTools:$IncludeManagementTools -Restart:$Restart -WhatIf:$WhatIf $success = $result -AND $result.Success $status = if ($success) { [UnInstallStatus]::Succeeded } Else { [UnInstallStatus]::Failed } } Catch { If ($success -AND $Restart -AND $result.restartNeeded -eq 'Yes') { $status = [UnInstallStatus]::Pending $error.clear() } Else { Throw } } } Else { $success = $True $status = [UnInstallStatus]::NotInstalled }} Else { $success = $False $status = [UnInstallStatus]::NoSuchFeature}@{ 'success' = $success ; 'status' = $status ; 'result' = $result }}## [END] Uninstall-RolesAndFeatures ##function Get-CimWin32ComputerSystem {<#.SYNOPSISGets Win32_ComputerSystem object..DESCRIPTIONGets Win32_ComputerSystem object..ROLEReaders#>##SkipCheck=true##import-module CimCmdletsGet-CimInstance -Namespace root/cimv2 -ClassName Win32_ComputerSystem}## [END] Get-CimWin32ComputerSystem ##function Get-CimWin32LogicalDisk {<#.SYNOPSISGets Win32_LogicalDisk object..DESCRIPTIONGets Win32_LogicalDisk object..ROLEReaders#>##SkipCheck=true##import-module CimCmdletsGet-CimInstance -Namespace root/cimv2 -ClassName Win32_LogicalDisk}## [END] Get-CimWin32LogicalDisk ##function Get-CimWin32NetworkAdapter {<#.SYNOPSISGets Win32_NetworkAdapter object..DESCRIPTIONGets Win32_NetworkAdapter object..ROLEReaders#>##SkipCheck=true##import-module CimCmdletsGet-CimInstance -Namespace root/cimv2 -ClassName Win32_NetworkAdapter}## [END] Get-CimWin32NetworkAdapter ##function Get-CimWin32OperatingSystem {<#.SYNOPSISGets Win32_OperatingSystem object..DESCRIPTIONGets Win32_OperatingSystem object..ROLEReaders#>##SkipCheck=true##import-module CimCmdletsGet-CimInstance -Namespace root/cimv2 -ClassName Win32_OperatingSystem}## [END] Get-CimWin32OperatingSystem ##function Get-CimWin32PhysicalMemory {<#.SYNOPSISGets Win32_PhysicalMemory object..DESCRIPTIONGets Win32_PhysicalMemory object..ROLEReaders#>##SkipCheck=true##import-module CimCmdletsGet-CimInstance -Namespace root/cimv2 -ClassName Win32_PhysicalMemory}## [END] Get-CimWin32PhysicalMemory ##function Get-CimWin32Processor {<#.SYNOPSISGets Win32_Processor object..DESCRIPTIONGets Win32_Processor object..ROLEReaders#>##SkipCheck=true##import-module CimCmdletsGet-CimInstance -Namespace root/cimv2 -ClassName Win32_Processor}## [END] Get-CimWin32Processor ##function Get-ClusterInventory {<#.SYNOPSISRetrieves the inventory data for a cluster..DESCRIPTIONRetrieves the inventory data for a cluster..ROLEReaders#>import-module CimCmdlets -ErrorAction SilentlyContinue# JEA code requires to pre-import the module (this is slow on failover cluster environment.)import-module FailoverClusters -ErrorAction SilentlyContinue<#.SYNOPSISGet the name of this computer..DESCRIPTIONGet the best available name for this computer. The FQDN is preferred, but when not avaialblethe NetBIOS name will be used instead.#>function getComputerName() { $computerSystem = Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue | Microsoft.PowerShell.Utility\Select-Object Name, DNSHostName if ($computerSystem) { $computerName = $computerSystem.DNSHostName if ($null -eq $computerName) { $computerName = $computerSystem.Name } return $computerName } return $null}<#.SYNOPSISAre the cluster PowerShell cmdlets installed on this server?.DESCRIPTIONAre the cluster PowerShell cmdlets installed on this server?#>function getIsClusterCmdletAvailable() { $cmdlet = Get-Command "Get-Cluster" -ErrorAction SilentlyContinue return !!$cmdlet}<#.SYNOPSISGet the MSCluster Cluster CIM instance from this server..DESCRIPTIONGet the MSCluster Cluster CIM instance from this server.#>function getClusterCimInstance() { $namespace = Get-CimInstance -Namespace root/MSCluster -ClassName __NAMESPACE -ErrorAction SilentlyContinue if ($namespace) { return Get-CimInstance -Namespace root/mscluster MSCluster_Cluster -ErrorAction SilentlyContinue | Microsoft.PowerShell.Utility\Select-Object fqdn, S2DEnabled } return $null}<#.SYNOPSISDetermines if the current cluster supports Failover Clusters Time Series Database..DESCRIPTIONUse the existance of the path value of cmdlet Get-StorageHealthSetting to determine if TSDB is supported or not.#>function getClusterPerformanceHistoryPath() { return $null -ne (Get-StorageSubSystem clus* | Get-StorageHealthSetting -Name "System.PerformanceHistory.Path")}<#.SYNOPSISGet some basic information about the cluster from the cluster..DESCRIPTIONGet the needed cluster properties from the cluster.#>function getClusterInfo() { $returnValues = @{} $returnValues.Fqdn = $null $returnValues.isS2DEnabled = $false $returnValues.isTsdbEnabled = $false $cluster = getClusterCimInstance if ($cluster) { $returnValues.Fqdn = $cluster.fqdn $isS2dEnabled = !!(Get-Member -InputObject $cluster -Name "S2DEnabled") -and ($cluster.S2DEnabled -eq 1) $returnValues.isS2DEnabled = $isS2dEnabled if ($isS2DEnabled) { $returnValues.isTsdbEnabled = getClusterPerformanceHistoryPath } else { $returnValues.isTsdbEnabled = $false } } return $returnValues}<#.SYNOPSISAre the cluster PowerShell Health cmdlets installed on this server?.DESCRIPTIONAre the cluster PowerShell Health cmdlets installed on this server?s#>function getisClusterHealthCmdletAvailable() { $cmdlet = Get-Command -Name "Get-HealthFault" -ErrorAction SilentlyContinue return !!$cmdlet}<#.SYNOPSISAre the Britannica (sddc management resources) available on the cluster?.DESCRIPTIONAre the Britannica (sddc management resources) available on the cluster?#>function getIsBritannicaEnabled() { return $null -ne (Get-CimInstance -Namespace root/sddc/management -ClassName SDDC_Cluster -ErrorAction SilentlyContinue)}<#.SYNOPSISAre the Britannica (sddc management resources) virtual machine available on the cluster?.DESCRIPTIONAre the Britannica (sddc management resources) virtual machine available on the cluster?#>function getIsBritannicaVirtualMachineEnabled() { return $null -ne (Get-CimInstance -Namespace root/sddc/management -ClassName SDDC_VirtualMachine -ErrorAction SilentlyContinue)}<#.SYNOPSISAre the Britannica (sddc management resources) virtual switch available on the cluster?.DESCRIPTIONAre the Britannica (sddc management resources) virtual switch available on the cluster?#>function getIsBritannicaVirtualSwitchEnabled() { return $null -ne (Get-CimInstance -Namespace root/sddc/management -ClassName SDDC_VirtualSwitch -ErrorAction SilentlyContinue)}############################################################################ main()###########################################################################$clusterInfo = getClusterInfo$result = New-Object PSObject$result | Add-Member -MemberType NoteProperty -Name 'Fqdn' -Value $clusterInfo.Fqdn$result | Add-Member -MemberType NoteProperty -Name 'IsS2DEnabled' -Value $clusterInfo.isS2DEnabled$result | Add-Member -MemberType NoteProperty -Name 'IsTsdbEnabled' -Value $clusterInfo.isTsdbEnabled$result | Add-Member -MemberType NoteProperty -Name 'IsClusterHealthCmdletAvailable' -Value (getIsClusterHealthCmdletAvailable)$result | Add-Member -MemberType NoteProperty -Name 'IsBritannicaEnabled' -Value (getIsBritannicaEnabled)$result | Add-Member -MemberType NoteProperty -Name 'IsBritannicaVirtualMachineEnabled' -Value (getIsBritannicaVirtualMachineEnabled)$result | Add-Member -MemberType NoteProperty -Name 'IsBritannicaVirtualSwitchEnabled' -Value (getIsBritannicaVirtualSwitchEnabled)$result | Add-Member -MemberType NoteProperty -Name 'IsClusterCmdletAvailable' -Value (getIsClusterCmdletAvailable)$result | Add-Member -MemberType NoteProperty -Name 'CurrentClusterNode' -Value (getComputerName)$result}## [END] Get-ClusterInventory ##function Get-ClusterNodes {<#.SYNOPSISRetrieves the inventory data for cluster nodes in a particular cluster..DESCRIPTIONRetrieves the inventory data for cluster nodes in a particular cluster..ROLEReaders#>import-module CimCmdlets# JEA code requires to pre-import the module (this is slow on failover cluster environment.)import-module FailoverClusters -ErrorAction SilentlyContinue################################################################################ Constants###############################################################################Set-Variable -Name LogName -Option Constant -Value "Microsoft-ServerManagementExperience" -ErrorAction SilentlyContinueSet-Variable -Name LogSource -Option Constant -Value "SMEScripts" -ErrorAction SilentlyContinueSet-Variable -Name ScriptName -Option Constant -Value $MyInvocation.ScriptName -ErrorAction SilentlyContinue<#.SYNOPSISAre the cluster PowerShell cmdlets installed?.DESCRIPTIONUse the Get-Command cmdlet to quickly test if the cluster PowerShell cmdletsare installed on this server.#>function getClusterPowerShellSupport() { $cmdletInfo = Get-Command 'Get-ClusterNode' -ErrorAction SilentlyContinue return $cmdletInfo -and $cmdletInfo.Name -eq "Get-ClusterNode"}<#.SYNOPSISGet the cluster nodes using the cluster CIM provider..DESCRIPTIONWhen the cluster PowerShell cmdlets are not available fallback to usingthe cluster CIM provider to get the needed information.#>function getClusterNodeCimInstances() { # Change the WMI property NodeDrainStatus to DrainStatus to match the PS cmdlet output. return Get-CimInstance -Namespace root/mscluster MSCluster_Node -ErrorAction SilentlyContinue | ` Microsoft.PowerShell.Utility\Select-Object @{Name="DrainStatus"; Expression={$_.NodeDrainStatus}}, DynamicWeight, Name, NodeWeight, FaultDomain, State}<#.SYNOPSISGet the cluster nodes using the cluster PowerShell cmdlets..DESCRIPTIONWhen the cluster PowerShell cmdlets are available use this preferred function.#>function getClusterNodePsInstances() { return Get-ClusterNode -ErrorAction SilentlyContinue | Microsoft.PowerShell.Utility\Select-Object DrainStatus, DynamicWeight, Name, NodeWeight, FaultDomain, State}<#.SYNOPSISUse DNS services to get the FQDN of the cluster NetBIOS name..DESCRIPTIONUse DNS services to get the FQDN of the cluster NetBIOS name..NotesIt is encouraged that the caller add their approprate -ErrorAction whencalling this function.#>function getClusterNodeFqdn([string]$clusterNodeName) { return ([System.Net.Dns]::GetHostEntry($clusterNodeName)).HostName}<#.SYNOPSISWrites message to event log as warning..DESCRIPTIONWrites message to event log as warning.#>function writeToEventLog([string]$message) { Microsoft.PowerShell.Management\New-EventLog -LogName $LogName -Source $LogSource -ErrorAction SilentlyContinue Microsoft.PowerShell.Management\Write-EventLog -LogName $LogName -Source $LogSource -EventId 0 -Category 0 -EntryType Warning ` -Message $message -ErrorAction SilentlyContinue}<#.SYNOPSISGet the cluster nodes..DESCRIPTIONWhen the cluster PowerShell cmdlets are available get the information about the cluster nodesusing PowerShell. When the cmdlets are not available use the Cluster CIM provider.#>function getClusterNodes() { $isClusterCmdletAvailable = getClusterPowerShellSupport if ($isClusterCmdletAvailable) { $clusterNodes = getClusterNodePsInstances } else { $clusterNodes = getClusterNodeCimInstances } $clusterNodeMap = @{} foreach ($clusterNode in $clusterNodes) { $clusterNodeName = $clusterNode.Name.ToLower() try { $clusterNodeFqdn = getClusterNodeFqdn $clusterNodeName -ErrorAction SilentlyContinue } catch { $clusterNodeFqdn = $clusterNodeName writeToEventLog "[$ScriptName]: The fqdn for node '$clusterNodeName' could not be obtained. Defaulting to machine name '$clusterNodeName'" } $clusterNodeResult = New-Object PSObject $clusterNodeResult | Add-Member -MemberType NoteProperty -Name 'FullyQualifiedDomainName' -Value $clusterNodeFqdn $clusterNodeResult | Add-Member -MemberType NoteProperty -Name 'Name' -Value $clusterNodeName $clusterNodeResult | Add-Member -MemberType NoteProperty -Name 'DynamicWeight' -Value $clusterNode.DynamicWeight $clusterNodeResult | Add-Member -MemberType NoteProperty -Name 'NodeWeight' -Value $clusterNode.NodeWeight $clusterNodeResult | Add-Member -MemberType NoteProperty -Name 'FaultDomain' -Value $clusterNode.FaultDomain $clusterNodeResult | Add-Member -MemberType NoteProperty -Name 'State' -Value $clusterNode.State $clusterNodeResult | Add-Member -MemberType NoteProperty -Name 'DrainStatus' -Value $clusterNode.DrainStatus $clusterNodeMap.Add($clusterNodeName, $clusterNodeResult) } return $clusterNodeMap}############################################################################ main()###########################################################################getClusterNodes}## [END] Get-ClusterNodes ##function Get-ServerInventory {<#.SYNOPSISRetrieves the inventory data for a server..DESCRIPTIONRetrieves the inventory data for a server..ROLEReaders#>Set-StrictMode -Version 5.0Import-Module CimCmdlets<#.SYNOPSISConverts an arbitrary version string into just 'Major.Minor'.DESCRIPTIONTo make OS version comparisons we only want to compare the major and minor version. Build number and/os CSD are not interesting.#>function convertOsVersion([string]$osVersion) { [Ref]$parsedVersion = $null if (![Version]::TryParse($osVersion, $parsedVersion)) { return $null } $version = [Version]$parsedVersion.Value return New-Object Version -ArgumentList $version.Major, $version.Minor}<#.SYNOPSISDetermines if CredSSP is enabled for the current server or client..DESCRIPTIONCheck the registry value for the CredSSP enabled state.#>function isCredSSPEnabled() { Set-Variable credSSPServicePath -Option Constant -Value "WSMan:\localhost\Service\Auth\CredSSP" Set-Variable credSSPClientPath -Option Constant -Value "WSMan:\localhost\Client\Auth\CredSSP" $credSSPServerEnabled = $false; $credSSPClientEnabled = $false; $credSSPServerService = Get-Item $credSSPServicePath -ErrorAction SilentlyContinue if ($credSSPServerService) { $credSSPServerEnabled = [System.Convert]::ToBoolean($credSSPServerService.Value) } $credSSPClientService = Get-Item $credSSPClientPath -ErrorAction SilentlyContinue if ($credSSPClientService) { $credSSPClientEnabled = [System.Convert]::ToBoolean($credSSPClientService.Value) } return ($credSSPServerEnabled -or $credSSPClientEnabled)}<#.SYNOPSISDetermines if the Hyper-V role is installed for the current server or client..DESCRIPTIONThe Hyper-V role is installed when the VMMS service is available. This is muchfaster then checking Get-WindowsFeature and works on Windows Client SKUs.#>function isHyperVRoleInstalled() { $vmmsService = Get-Service -Name "VMMS" -ErrorAction SilentlyContinue return $vmmsService -and $vmmsService.Name -eq "VMMS"}<#.SYNOPSISDetermines if the Hyper-V PowerShell support module is installed for the current server or client..DESCRIPTIONThe Hyper-V PowerShell support module is installed when the modules cmdlets are available. This is muchfaster then checking Get-WindowsFeature and works on Windows Client SKUs.#>function isHyperVPowerShellSupportInstalled() { # quicker way to find the module existence. it doesn't load the module. return !!(Get-Module -ListAvailable Hyper-V -ErrorAction SilentlyContinue)}<#.SYNOPSISDetermines if Windows Management Framework (WMF) 5.0, or higher, is installed for the current server or client..DESCRIPTIONWindows Admin Center requires WMF 5 so check the registey for WMF version on Windows versions that are less thanWindows Server 2016.#>function isWMF5Installed([string] $operatingSystemVersion) { Set-Variable Server2016 -Option Constant -Value (New-Object Version '10.0') # And Windows 10 client SKUs Set-Variable Server2012 -Option Constant -Value (New-Object Version '6.2') $version = convertOsVersion $operatingSystemVersion if (-not $version) { # Since the OS version string is not properly formatted we cannot know the true installed state. return $false } if ($version -ge $Server2016) { # It's okay to assume that 2016 and up comes with WMF 5 or higher installed return $true } else { if ($version -ge $Server2012) { # Windows 2012/2012R2 are supported as long as WMF 5 or higher is installed $registryKey = 'HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine' $registryKeyValue = Get-ItemProperty -Path $registryKey -Name PowerShellVersion -ErrorAction SilentlyContinue if ($registryKeyValue -and ($registryKeyValue.PowerShellVersion.Length -ne 0)) { $installedWmfVersion = [Version]$registryKeyValue.PowerShellVersion if ($installedWmfVersion -ge [Version]'5.0') { return $true } } } } return $false}<#.SYNOPSISDetermines if the current usser is a system administrator of the current server or client..DESCRIPTIONDetermines if the current usser is a system administrator of the current server or client.#>function isUserAnAdministrator() { return ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")}<#.SYNOPSISGet some basic information about the Failover Cluster that is running on this server..DESCRIPTIONCreate a basic inventory of the Failover Cluster that may be running in this server.#>function getClusterInformation() { $returnValues = @{} $returnValues.IsS2dEnabled = $false $returnValues.IsCluster = $false $returnValues.ClusterFqdn = $null $namespace = Get-CimInstance -Namespace root/MSCluster -ClassName __NAMESPACE -ErrorAction SilentlyContinue if ($namespace) { $cluster = Get-CimInstance -Namespace root/MSCluster -ClassName MSCluster_Cluster -ErrorAction SilentlyContinue if ($cluster) { $returnValues.IsCluster = $true $returnValues.ClusterFqdn = $cluster.Fqdn $returnValues.IsS2dEnabled = !!(Get-Member -InputObject $cluster -Name "S2DEnabled") -and ($cluster.S2DEnabled -gt 0) } } return $returnValues}<#.SYNOPSISGet the Fully Qaulified Domain (DNS domain) Name (FQDN) of the passed in computer name..DESCRIPTIONGet the Fully Qaulified Domain (DNS domain) Name (FQDN) of the passed in computer name.#>function getComputerFqdnAndAddress($computerName) { $hostEntry = [System.Net.Dns]::GetHostEntry($computerName) $addressList = @() foreach ($item in $hostEntry.AddressList) { $address = New-Object PSObject $address | Add-Member -MemberType NoteProperty -Name 'IpAddress' -Value $item.ToString() $address | Add-Member -MemberType NoteProperty -Name 'AddressFamily' -Value $item.AddressFamily.ToString() $addressList += $address } $result = New-Object PSObject $result | Add-Member -MemberType NoteProperty -Name 'Fqdn' -Value $hostEntry.HostName $result | Add-Member -MemberType NoteProperty -Name 'AddressList' -Value $addressList return $result}<#.SYNOPSISGet the Fully Qaulified Domain (DNS domain) Name (FQDN) of the current server or client..DESCRIPTIONGet the Fully Qaulified Domain (DNS domain) Name (FQDN) of the current server or client.#>function getHostFqdnAndAddress($computerSystem) { $computerName = $computerSystem.DNSHostName if (!$computerName) { $computerName = $computerSystem.Name } return getComputerFqdnAndAddress $computerName}<#.SYNOPSISAre the needed management CIM interfaces available on the current server or client..DESCRIPTIONCheck for the presence of the required server management CIM interfaces.#>function getManagementToolsSupportInformation() { $returnValues = @{} $returnValues.ManagementToolsAvailable = $false $returnValues.ServerManagerAvailable = $false $namespaces = Get-CimInstance -Namespace root/microsoft/windows -ClassName __NAMESPACE -ErrorAction SilentlyContinue if ($namespaces) { $returnValues.ManagementToolsAvailable = !!($namespaces | Where-Object { $_.Name -ieq "ManagementTools" }) $returnValues.ServerManagerAvailable = !!($namespaces | Where-Object { $_.Name -ieq "ServerManager" }) } return $returnValues}<#.SYNOPSISCheck the remote app enabled or not..DESCRIPTIONCheck the remote app enabled or not.#>function isRemoteAppEnabled() { Set-Variable key -Option Constant -Value "HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\TSAppAllowList" $registryKeyValue = Get-ItemProperty -Path $key -Name fDisabledAllowList -ErrorAction SilentlyContinue if (-not $registryKeyValue) { return $false } return $registryKeyValue.fDisabledAllowList -eq 1}<#.SYNOPSISCheck the remote app enabled or not..DESCRIPTIONCheck the remote app enabled or not.#><#c.SYNOPSISGet the Win32_OperatingSystem information.DESCRIPTIONGet the Win32_OperatingSystem instance and filter the results to just the required properties.This filtering will make the response payload much smaller.#>function getOperatingSystemInfo() { return Get-CimInstance Win32_OperatingSystem | Microsoft.PowerShell.Utility\Select-Object csName, Caption, OperatingSystemSKU, Version, ProductType}<#.SYNOPSISGet the Win32_ComputerSystem information.DESCRIPTIONGet the Win32_ComputerSystem instance and filter the results to just the required properties.This filtering will make the response payload much smaller.#>function getComputerSystemInfo() { return Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue | ` Microsoft.PowerShell.Utility\Select-Object TotalPhysicalMemory, DomainRole, Manufacturer, Model, NumberOfLogicalProcessors, Domain, Workgroup, DNSHostName, Name, PartOfDomain}############################################################################ main()###########################################################################$operatingSystem = getOperatingSystemInfo$computerSystem = getComputerSystemInfo$isAdministrator = isUserAnAdministrator$fqdnAndAddress = getHostFqdnAndAddress $computerSystem$hostname = hostname$netbios = $env:ComputerName$managementToolsInformation = getManagementToolsSupportInformation$isWmfInstalled = isWMF5Installed $operatingSystem.Version$clusterInformation = getClusterInformation -ErrorAction SilentlyContinue$isHyperVPowershellInstalled = isHyperVPowerShellSupportInstalled$isHyperVRoleInstalled = isHyperVRoleInstalled$isCredSSPEnabled = isCredSSPEnabled$isRemoteAppEnabled = isRemoteAppEnabled$result = New-Object PSObject$result | Add-Member -MemberType NoteProperty -Name 'IsAdministrator' -Value $isAdministrator$result | Add-Member -MemberType NoteProperty -Name 'OperatingSystem' -Value $operatingSystem$result | Add-Member -MemberType NoteProperty -Name 'ComputerSystem' -Value $computerSystem$result | Add-Member -MemberType NoteProperty -Name 'Fqdn' -Value $fqdnAndAddress.Fqdn$result | Add-Member -MemberType NoteProperty -Name 'AddressList' -Value $fqdnAndAddress.AddressList$result | Add-Member -MemberType NoteProperty -Name 'Hostname' -Value $hostname$result | Add-Member -MemberType NoteProperty -Name 'NetBios' -Value $netbios$result | Add-Member -MemberType NoteProperty -Name 'IsManagementToolsAvailable' -Value $managementToolsInformation.ManagementToolsAvailable$result | Add-Member -MemberType NoteProperty -Name 'IsServerManagerAvailable' -Value $managementToolsInformation.ServerManagerAvailable$result | Add-Member -MemberType NoteProperty -Name 'IsWmfInstalled' -Value $isWmfInstalled$result | Add-Member -MemberType NoteProperty -Name 'IsCluster' -Value $clusterInformation.IsCluster$result | Add-Member -MemberType NoteProperty -Name 'ClusterFqdn' -Value $clusterInformation.ClusterFqdn$result | Add-Member -MemberType NoteProperty -Name 'IsS2dEnabled' -Value $clusterInformation.IsS2dEnabled$result | Add-Member -MemberType NoteProperty -Name 'IsHyperVRoleInstalled' -Value $isHyperVRoleInstalled$result | Add-Member -MemberType NoteProperty -Name 'IsHyperVPowershellInstalled' -Value $isHyperVPowershellInstalled$result | Add-Member -MemberType NoteProperty -Name 'IsCredSSPEnabled' -Value $isCredSSPEnabled$result | Add-Member -MemberType NoteProperty -Name 'IsRemoteAppEnabled' -Value $isRemoteAppEnabled$result}Kaynak: Dokuman Microsoft admin center üzerinden alınmıştır.