# # ---------------------------- # XSD SCHEMA DEFINITION # ---------------------------- # # # ----------------------------- # SCHEMATRON RULES DEFINITION # ----------------------------- # # # -------------------------------------------------- # TRANSLATIONS DEFINITION - See EN-US Sub-directory # ------------------------------------------------- # Import-LocalizedData -BindingVariable _system_translations -filename WorkFolders.psd1 $windir = $env:Windir . $windir\System32\BestPractices\v1.0\Models\Microsoft\Windows\FileServices\fscommon.ps1 # # -------------------------------------------------- # CONSTANTS DEFINITION # ------------------------------------------------- # $enum = " [System.Flags] public enum firewallstate { SSLHTTP = 0, SSLONLY = 1, HTTPONLY = 2, NOPORTS=3 } " Add-Type -TypeDefinition $enum $sslenum = " [System.Flags] public enum certificatestate { OK = 0, NOSSL = 1, NOCERT = 2, CERTEXPIRING = 3 , CERTEXPIRED = 4 } " Add-Type -TypeDefinition $sslenum $systemRoot = (Get-Item Env:\SystemRoot).value #WorkFolders configuration file $xmlFile = $systemRoot +"\System32\SyncShareSvc.config” #Days to start warning for a cert expiring $DaysToExpiration = 75 #document to hold expired or expiring certificate information $global:certificateXML = ""; #snippet string to for blocked ports $global:blockedPorts = ""; # # ------------------ # FUNCTIONS - START # ------------------ # ################################################################################################ # Check to see if the work folder server is actively joined to a domain # Note: we do not use # (gwmi Win32_NTDomain).DomainName # or # (gwmi win32_computersystem).PartofDomain # # Both functions return the local information and does not reflect # if the computer domain is a real domain. # The wmi(gwmi) calls are also signficantly slower than using the .net calls, # with the .Net calls typically being 200x faster # The gwmi call, Win32_NTDomain, returns all of the domains the computer knows about # and not just the joined domains. Thus the check for Domain could return a false positive ################################################################################################# function CheckWorkFoldersSyncServerJoined { $answer = $false $domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().Name if($domain -ne $null){ $answer = $true } return $answer } function checkWorkFoldersSyncShareStagingExist { #Iterate over the staging folders and if one doesn't exist return false which will triger the BPA $var = Get-SyncShare if ($var -eq $null) { return $true } else { foreach ($syncShare in get-SyncShare){if( (Test-Path $syncShare.StagingFolder) -eq $false){return $false}} } return $true } function CheckWorkFoldersSyncSharePathExist { #Iterate over the SyncShare folders and if one doesn't exist return false which will triger the BPA $var = Get-SyncShare if ($var -eq $null) { return $true } else { foreach ($syncShare in get-SyncShare){if( (Test-Path $syncShare.Path) -eq $false){return $false}} } return $true } ######################################################## # Master Firewall switch method # if any site fails break out of loop ################################################################### function WorkFoldersFirewallFlag($foundSites) { $answer = [firewallState]::SSLHTTP ForEach ($aSite in $foundSites ){ $answer = checkFirewall( $aSite ) if( $answer -ne "SSLHTTP" ) { break } } return $answer } ######################################################## #check firewall rules # http://technet.microsoft.com/en-us/library/cc770685(v=ws.10).aspx # # Protocol: 6 = TCP # # Action: 1 = Block # 2 = Allow # # Direction: 1 = In # 2 = Out # # Type: 1 = Domain # 2 = Private # 4 = Public # # Obtain a list of all enabled FireWall Rules on the machine with Get-NetFireWall # -- ActiveStore: This store contains the currently active policy, which is the sum of all policy stores that apply to the computer. This is # the resultant set of policy (RSOP) for the local computer (the sum of all GPOs that apply to the computer), and the local stores (the # PersistentStore, the static Windows service hardening (WSH), and the configurable WSH). # # -- PersistentStore: Sometimes called static rules, this store contains the persistent policy for the local computer. This policy is not # from GPOs, and has been created manually or programmatically (during application installation) on the computer. Rules created in this store # are attached to the ActiveStore and activated on the computer immediately. # # hnetcfg.fwpolicy2 only retrieves rules assigned in local store # http://technet.microsoft.com/en-us/library/jj554860.aspx # # Firewall Rules can be stored in two locations. # assigned for local computer - 'Registry::HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules' # assigned by group policy - 'Registry::HKLM\Software\Policies\Microsoft\WindowsFirewall\FirewallRules # ################################################################################################################################################ function checkFirewall( $siteIn ) { # do PortCheck, IPV6 firewall rules do not bind to port and need further investigation. # these rules are only valid for IPV4 # First filter retrieves Rules that are Enabled(1), Allowed (Action=2), In (Direction=1) and are enabled for either All networks or at least Domain. # Final filter limits to TCP and Rules that have ports that are listed in the ShareSyncSvc.config file # # If a Rule for a port is configured for Private Network or Public network then a NOPORTS error will be returned # $enabledRules= ( Get-NetFirewallRule -All -PolicyStore ActiveStore | Where { $_.Enabled.value__ -eq 1 -and $_.Action.value__ -eq 2 -and $_.Direction.value__ -eq 1 -and ( $_.Profile -eq "Any" -or ($_.Profile.toString()).ToLower().Contains("Domain".ToLower()) ) }| Get-NetFirewallPortFilter | Where { $_.Protocol -eq "TCP" -and $aSite.Bindings.Port -contains ([array]$_.LocalPort)[0] } ) if ( $enabledRules.Count -eq 0) { foreach($abinding in $aSite.Bindings) { $global:blockedPorts +=, @{$true="" + $abinding.IP +":"+ $abinding.Port; $false=", " + $abinding.IP +":"+ + $abinding.Port}[($global:blockedPorts.length -eq 0)] } $global:blockedPorts +=, "" return [firewallState]::NOPORTS } #create xml list of all blocked ports $global:blockedPorts +=, "" $portString = "" foreach($abinding in $aSite.Bindings) { $aIP = $abinding.IP if( $aIP -ne "*" ) { $ipcheck = Get-NetFirewallRule -All -PolicyStore ActiveStore | Where { $_.Enabled.value__ -eq 1 -and $_.Action.value__ -eq 2 -and $_.Direction.value__ -eq 1} | Get-NetFirewallAddressFilter | Where { $_.LocalAddress -eq $aIP } if($ipcheck -eq $null) { $portString +=, @{$true= $abinding.IP +":"+ $abinding.Port; $false=", " + $abinding.IP +":"+ + $abinding.Port}[($portString.length -eq 0)] } } elseif(([array]$enabledRules.LocalPort) -notcontains $abinding.Port ) { $portString +=, @{$true= $abinding.IP +":"+ $abinding.Port; $false=", " + $abinding.IP +":"+ + $abinding.Port}[($portString.length -eq 0)] } } $global:blockedPorts +=, $portString +"" #check if site only has http bound if ( ($siteIn.Bindings.Protocol -contains "http") -and ($siteIn.Bindings.Protocol -notcontains "https") ) { # if one port is not bound then fail all if(! (-not @($aSite.Bindings.Port| where {([array]$enabledRules.LocalPort) -notcontains $_}| select -first 1).Count)) { return [firewallState]::NOPORTS } else { return [firewallState]::HTTPONLY } } #check if site only has https bound if ( ($siteIn.Bindings.Protocol -contains "https") -and ($siteIn.Bindings.Protocol -notcontains "http") ) { # if one port is not bound then fail all if(! (-not @($aSite.Bindings.Port| where {([array]$enabledRules.LocalPort) -notcontains $_}| select -first 1).Count)) { return [firewallState]::NOPORTS } else { return [firewallState]::SSLONLY } } #check if site only has both protocols bound if ( ($siteIn.Bindings.Protocol -contains "https") -and ($siteIn.Bindings.Protocol -contains "http") ) { # if one port is not bound then fail all ForEach($selectedBinding in $siteIn.Bindings) { if( $selectedBinding.Protocol -eq "http" -and !(-not @($selectedBinding.Port| where {([array]$enabledRules.LocalPort) -notcontains $_}| select -first 1).Count)) { return [firewallState]::SSLONLY } if( $selectedBinding.Protocol -eq "https" -and !(-not @($selectedBinding.Port| where {([array]$enabledRules.LocalPort) -notcontains $_}| select -first 1).Count)) { return [firewallState]::HTTPONLY } } } #check if there is an IP to see if IP is specified # ForEach( $aIP in $aSite.Bindings.IP ) { if( $aIP -ne "*" ) { $ipcheck = Get-NetFirewallRule -All -PolicyStore ActiveStore | Where { $_.Enabled.value__ -eq 1 -and $_.Action.value__ -eq 2 -and $_.Direction.value__ -eq 1} | Get-NetFirewallAddressFilter | Where { $_.LocalAddress -eq $aIP } if($ipcheck -eq $null) { return [firewallState]::NOPORTS } } } return [firewallState]::SSLHTTP } ########################################################## # Create a list of sites from the SyncShareSvc.config ########################################################## function GetSites() { $sites = @() $bindings = @() ########################################################## # Read the SyncShareSvc.config and populate variables ########################################################## $xmlDoc = [XML](Get-Content $xmlFile) if ($xmlDoc -ne $null) { foreach ( $site in $xmlDoc.configuration.'system.applicationHost'.sites.site) { $objSite = New-Object System.Object $objSite | Add-Member -type NoteProperty -name Name -value $site.Name ########################################################## # Read the site bindings ######################################################### foreach ( $binding in $site.bindings.binding) { $objBinding = New-Object System.Object $objBinding | Add-Member -type NoteProperty -name Protocol -value $binding.protocol ################################################################################################## # Parse bindings into IP Address, Port and HostName # format is ipaddress:port:hostname ################################################################################################## $tokens = $binding.bindingInformation.Split(":") $objBinding | Add-Member -type NoteProperty -name IP -value $tokens[0] $objBinding | Add-Member -type NoteProperty -name Port -value $tokens[1] $objBinding | Add-Member -type NoteProperty -name HostName -value $tokens[2] ################################################################################################## #sslFlags can have one of the following values. Default is none # #Value Description #None Disable SSL. The numeric value is 0. #Ssl Require SSL. The numeric value is 8. #SslNegotiateCert Accept client certificates for authentication. The numeric value is 32. #SslRequireCert Require clients certificates for authentication. The numeric value is 64. #Ssl128 Require 128-bit SSL. The numeric value is 256. # ################################################################################################### $objBinding | Add-Member -type NoteProperty -name sslFlags -value $binding.sslFlags $bindings +=, $objBinding } $objSite | Add-Member -type NoteProperty -name Bindings -value $bindings $sites +=, $objSite } } return $sites } ########################################################## # Create sitesxml ########################################################## function GetSitesXML( $foundSites) { if ($foundSites -ne $null) { $httpport = "" $sslport = "" $allport = "" $httpportbinding = "" $sslportbinding = "" $allportbinding = "" @" $( foreach ($site in $foundSites) { foreach ($binding in $site.Bindings) { #powershell doesn't support ternary, but this works if($binding.sslFlags.length -eq 0 ) { $httpport +=, @{$true=$binding.Port; $false=", "+ $binding.Port}[($httpport.length -eq 0)] $httpportbinding +=, @{$true= $binding.IP+":"+ $binding.Port; $false=", "+ $binding.IP+":"+ $binding.Port}[($httpportbinding.length -eq 0)] } if($binding.sslFlags.length -gt 0){ $sslport +=, @{$true=$binding.Port; $false=", "+ $binding.Port}[($sslport.length -eq 0)] $sslportbinding +=, @{$true= $binding.IP+":"+ $binding.Port; $false=", "+ $binding.IP+":"+ $binding.Port}[($sslportbinding.length -eq 0)] } $allport +=, @{$true=$binding.Port; $false=", "+ $binding.Port}[($allport.length -eq 0)] $allportbinding +=, @{$true= $binding.IP+":"+ $binding.Port; $false=", "+ $binding.IP+":"+ $binding.Port}[($allportbinding.length -eq 0)] } } @" $httpport $sslport $allport $httpportbinding $sslportbinding $allportbinding "@ ) "@ } else { @" "@ } } ########################################################## # Create certificatesxml ########################################################## function createCertXML($ip,$port,$store,$hash) { $_ip = $ip $_port = $port $_store = $store $_hash = $hash @" $_ip $_port $_store $_hash "@ } ########################################################## # Master check cert method ########################################################## function checkCerts( $foundSites ) { $answer =[certificatestate]::OK ########################################################## # Only check sites that have https ########################################################## ForEach ($aSite in $foundSites| Where {$_.Bindings.Protocol -notcontains("https") } ){ $answer =[certificatestate]::NOSSL return $answer } ########################################################## # Only check sites that have https ########################################################## ForEach ($aSite in $foundSites| Where {$_.Bindings.Protocol.Contains("https") } ){ $certAssignedSSLPorts = checkSSLPortCert($aSite ) if($certAssignedSSLPorts) { $answer =[certificatestate]::NOCERT return $answer } $expiringHWCCert = checkHWCExpiringCerts($aSite ) if($expiringHWCCert) { $answer =[certificatestate]::CERTEXPIRING return $answer } $expiredHWCCert = checkHWCExpiredCerts($aSite ) if($expiredHWCCert) { $answer =[certificatestate]::CERTEXPIRED return $answer } $expiringIISCert = checkIISExpiringCerts($aSite ) if($expiringIISCert) { $answer =[certificatestate]::CERTEXPIRING return $answer } $expiredIISCert = checkIISExpiredCerts($aSite ) if($expiredIISCert) { $answer =[certificatestate]::CERTEXPIRED # "Cert bound to Work Folders has expired" return $answer } return $answer } } ######################################################### #Start checking 75 days before expiration to provide time #to reorder cert ######################################################### function checkIISExpiringCerts( $siteIn ) { #Date used to calculate the difference from certificate exipartion date $expirationWarningDate = (Get-Date).AddDays($DaysToExpiration) ########################################################## # Only check the running site. If SiteName matches what # SyncShareSvc.config, the Service is under IIS ########################################################## $sites = Get-Website | ? { $_.State -eq "Started" -and $_.Name -eq $siteIn.Name } | % { $_.Name } ########################################################## # Site is not running under IIS so return ########################################################## if ($sites.Count -lt 1) { return $false; } $certs = Get-ChildItem IIS:SSLBindings | ? { $sites -contains $_.Sites.Value } | % { $_.Thumbprint } ########################################################## # Check the local machine cert webhosting store ########################################################## $webhostingstorecert = Get-ChildItem -Path cert:\LocalMachine\WebHosting -ExpiringInDays $DaysToExpiration | ?{ $certs -contains $_.Thumbprint -and ( ($_.NotAfter.DayOfYear - $expirationWarningDate.DayOfYear -gt 0) -and ($_.NotAfter.DayOfYear - $expirationWarningDate.DayOfYear -lt $DaysToExpiration+1) ) } ########################################################## # Check the localmachine cert personal store ########################################################## $localpersonalstorecert = Get-ChildItem -Path cert:\LocalMachine\My -ExpiringInDays $DaysToExpiration | ?{ $certs -contains $_.Thumbprint -and ( ($_.NotAfter.DayOfYear - $expirationWarningDate.DayOfYear -gt 0) -and ($_.NotAfter.DayOfYear - $expirationWarningDate.DayOfYear -lt $DaysToExpiration+1) ) } if( $webhostingstorecert.Count -gt 0 -or $localpersonalstorecert.Count -gt 0 ) { return $true } return $false } ########################################################## # Check to ensure site has SSL enabled on site ########################################################## function checkSSLEnabled( $siteIn ) { ForEach ($aSite in $foundSites| Where {$_.Bindings.Protocol -notcontains("https") } ){ return $true } return $false } ######################################################### #Check if any cert bound to IIS are expired # ######################################################### function checkIISExpiredCerts( $siteIn ) { $expirationWarningDate = (Get-Date) ########################################################## # Only check the running site. If SiteName matches what # SyncShareSvc.config, the Service is under IIS ########################################################## $sites = Get-Website | ? { $_.State -eq "Started" -and $_.Name -eq $siteIn.Name } | % { $_.Name } ########################################################## # Site is not running under IIS so return ########################################################## if ($sites.Count -lt 1) { return $false; } $certs = Get-ChildItem IIS:SSLBindings | ? { $sites -contains $_.Sites.Value } | % { $_.Thumbprint } ########################################################## # Check the local machine cert webhosting store ########################################################## $webhostingstorecert = Get-ChildItem -Path cert:\LocalMachine\WebHosting | ?{ $certs -contains $_.Thumbprint -and $expirationWarningDate -gt $_.NotAfter } ########################################################## # Check the localmachine cert personal store ########################################################## $localpersonalstorecert = Get-ChildItem -Path cert:\LocalMachine\My | ?{ $certs -contains $_.Thumbprint -and $expirationWarningDate -gt $_.NotAfter } if( $webhostingstorecert.Count -gt 0 -or $localpersonalstorecert.Count -gt 0 ) { return $true } return $false } ######################################################### #Start checking 75 days before expiration to provide time #to reorder cert ######################################################### function checkHWCExpiringCerts( $siteIn ) { $arrService = Get-Service -Name "SyncShareSvc" if ($arrService.Status -ne "Running"){ return $false } $expirationWarningDate = (Get-Date).AddDays($DaysToExpiration) $ip = "" $port = "" ForEach ($aBinding in $siteIn.Bindings| Where {$_.Protocol.Contains("https") } ){ if($aBinding.IP -eq "*"){ # retrieve list of all bound certs on machine $allcerts = netsh http show sslcert # convert list to object list and filter on matchine port $certs= Get-NetshCertificates($allcerts)| Where {$_.Port -eq $aBinding.Port } if( $certs -ne $null ) { $ip = "*" $port = $aBinding.Port } } else { $address = "$($aBinding.IP)"+":"+"$($aBinding.Port)" #a specific IP is listed, so just retrieve the cert bound to that port and IP $allcerts = netsh http show sslcert ipport=$address # convert to object list $certs= Get-NetshCertificates($allcerts) if( $certs -ne $null) { $ip = $aBinding.IP $port = $aBinding.Port } } ########################################################## # Check the local machine cert webhosting store ########################################################## $webhostingstorecert = Get-ChildItem -Path cert:\LocalMachine\WebHosting -ExpiringInDays $DaysToExpiration | ?{ $certs.Thumbprint -contains $_.Thumbprint -and ( ($expirationWarningDate.DayOfYear - $_.NotAfter.DayOfYear -gt 0) -and ( $expirationWarningDate.DayOfYear - $_.NotAfter.DayOfYear -le $DaysToExpiration) ) } ########################################################## # Check the localmachine cert personal store ########################################################## $localpersonalstorecert = Get-ChildItem -Path cert:\LocalMachine\My -ExpiringInDays $DaysToExpiration | ?{ $certs.Thumbprint -contains $_.Thumbprint -and ( ( $expirationWarningDate.DayOfYear - $_.NotAfter.DayOfYear -gt 0) -and ( $expirationWarningDate.DayOfYear - $_.NotAfter.DayOfYear -le $DaysToExpiration) ) } $hash = "" $store = "" if( $webhostingstorecert.Count -gt 0 ) { $store = "LocalMachine\WebHosting" $hash = $webhostingstorecert.Thumbprint } if( $localpersonalstorecert.Count -gt 0) { $store = "LocalMachine\My" $hash = $localpersonalstorecert.Thumbprint } if( $webhostingstorecert.Count -gt 0 -or $localpersonalstorecert.Count -gt 0) { $global:certificateXML = createCertXML $ip $port $store $hash return $true } } return $false } ######################################################### #Notify of invalid cert for HWC # ######################################################### function checkHWCExpiredCerts( $siteIn ) { $arrService = Get-Service -Name "SyncShareSvc" if ($arrService.Status -ne "Running"){ return $false } $ip = "" $port = "" $expirationWarningDate = Get-Date # $expirationWarningDate = (Get-Date).AddDays($DaysToExpiration) ForEach ($aBinding in $siteIn.Bindings| Where {$_.Protocol.Contains("https") } ){ if($aBinding.IP -eq "*"){ # retrieve list of all bound certs on machine $allcerts = netsh http show sslcert # convert list to object list and filter on matchine port $certs= Get-NetshCertificates($allcerts)| Where {$_.Port -eq $aBinding.Port } if( $certs -ne $null ) { $ip = "*" $port = $aBinding.Port } } else { $address = "$($aBinding.IP)"+":"+"$($aBinding.Port)" #a specific IP is listed, so just retrieve the cert bound to that port and IP $allcerts = netsh http show sslcert ipport=$address # convert to object list $certs= Get-NetshCertificates($allcerts) if( $certs -ne $null ) { $ip = $aBinding.IP $port = $aBinding.Port } } ########################################################## # Check the local machine cert webhosting store ########################################################## $webhostingstorecert = Get-ChildItem -Path cert:\LocalMachine\WebHosting | ?{ $certs.Thumbprint -contains $_.Thumbprint -and $expirationWarningDate -gt $_.NotAfter } ########################################################## # Check the localmachine cert personal store ########################################################## $localpersonalstorecert = Get-ChildItem -Path cert:\LocalMachine\My | ?{ $certs.Thumbprint -contains $_.Thumbprint -and $expirationWarningDate -gt $_.NotAfter } $hash = "" $store = "" if( $webhostingstorecert.Count -gt 0 ) { $store = "LocalMachine\WebHosting" $hash = $webhostingstorecert.Thumbprint } if( $localpersonalstorecert.Count -gt 0) { $store = "LocalMachine\My" $hash = $localpersonalstorecert.Thumbprint } if( $webhostingstorecert.Count -gt 0 -or $localpersonalstorecert.Count -gt 0) { $global:certificateXML = createCertXML $ip $port $store $hash return $true } } return $false } ######################################################### #Check to see if specificed SSL port(s) have a certificate #assigned ######################################################### function checkSSLPortCert( $siteIn ) { $arrService = Get-Service -Name "SyncShareSvc" if ($arrService.Status -ne "Running"){ return $false } ForEach ($aBinding in $siteIn.Bindings| Where {$_.Protocol.Contains("https") } ){ if($aBinding.IP -eq "*"){ # retrieve list of all bound certs on machine $allcerts = netsh http show sslcert # convert list to object list and filter on matchine port $certs= Get-NetshCertificates($allcerts)| Where {$_.Port -eq $aBinding.Port } } else { $address = "$($aBinding.IP)"+":"+"$($aBinding.Port)" #a specific IP is listed, so just retrieve the cert bound to that port and IP $allcerts = netsh http show sslcert ipport=$address # convert to object list $certs= Get-NetshCertificates($allcerts) } ##################################################### #check that $certs is not null and contains a cert #################################################### if( !$certs ) { return $true } } return $false } ################################################################# # take the raw output from netsh http show sslcert and covert # to a list of objects with IP, Port and Thumbprint ################################################################# Function Get-NetshCertificates($rawInput) { ################################################################# # Trim the raw out put to remove the below leading strings ################################################################# $rawInput = $rawInput[3..($rawInput.length-2)] #Parsing each line using regular expressions $certs = $(switch -regex ($rawInput) { #IP:Port 'IP:port' { #Create new object and put it into $CurrentObject $CurrentObject = New-Object -Type PSObject #If line contains "IP:port"... if ($_ -match '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,5}') { #Add IP and Port $ipport = $Matches.Values[0] $token = $ipport.Split(":") $CurrentObject | Add-Member -type NoteProperty -Name "IP" -Value $token[0] $CurrentObject | Add-Member -type NoteProperty -Name "Port" -Value $token[1] } } # Get Certificate thumbprint 'Certificate Hash' { if ($_ -match '([^:]*)$') { #Remove any leading/trailing spaces from certificate thumbprint $thumbprint = $Matches[0] -replace ' ' $CurrentObject | Add-Member -type NoteProperty -name "Thumbprint" -Value $thumbprint } if ($CurrentObject) {Write-Output $CurrentObject} } }) return $certs } # # X M L R E P O R T - generates the XML report for all BPA Rules # function GetWorkFoldersXml($xmlDoc, $ns) { $WorkFoldersNode = $xmlDoc.CreateElement("WorkFolders", $ns) [void]$xmlDoc.DocumentElement.AppendChild($WorkFoldersNode) $computerName = [System.Net.Dns]::GetHostName() $WorkFoldersServiceStatus = Check-ServiceStatus $computerName "SyncShareSvc" Append-XmlElement $xmlDoc $WorkFoldersNode $ns "ServiceRunning" (Formalize-BoolValue $WorkFoldersServiceStatus) # Only do the rest of the rules if the service is running if($WorkFoldersServiceStatus) { #if service is running there must be a config file in place, so it's safe to call Get-Sites here $foundSites = GetSites if(Get-ServerInClusterStatus) { $clusterElement = $xmlDoc.CreateElement("Cluster", $ns) [void]$WorkFoldersNode.AppendChild($clusterElement) $isServiceInstallationConsistent = Check-ServiceInstalationOnCluster "Work Folders" Append-XmlElement $xmlDoc $clusterElement $ns "ServiceInstallationOnClusterConsistent" $isServiceInstallationConsistent[0] if($isServiceInstallationConsistent[0] -eq "NA") { Append-XmlElement $xmlDoc $clusterElement $ns "NotReachableNodes" $isServiceInstallationConsistent[1] } } $WorkFoldersSyncServerJoined = CheckWorkFoldersSyncServerJoined Append-XmlElement $xmlDoc $WorkFoldersNode $ns "WFServerJoined" (Formalize-BoolValue $WorkFoldersSyncServerJoined) $WorkFoldersSyncShareStagingExist = CheckWorkFoldersSyncShareStagingExist Append-XmlElement $xmlDoc $WorkFoldersNode $ns "SyncShareStagingExists" (Formalize-BoolValue $WorkFoldersSyncShareStagingExist) $WorkFoldersSyncSharePathExist = CheckWorkFoldersSyncSharePathExist Append-XmlElement $xmlDoc $WorkFoldersNode $ns "SyncSharePathExists" (Formalize-BoolValue $WorkFoldersSyncSharePathExist) $WorkFoldersServerSSLCertExistsFlag = checkCerts($foundSites) ##these messages need to be verified by willge Append-XmlElement $xmlDoc $WorkFoldersNode $ns "ServerSSLCertExists" ($WorkFoldersServerSSLCertExistsFlag) $WorkFoldersFirewallFlag = WorkFoldersFirewallFlag($foundSites) ##these messages need to be verified by willge Append-XmlElement $xmlDoc $WorkFoldersNode $ns "FirewallRulesValid" ($WorkFoldersFirewallFlag) $sitesDoc = GetSitesXML($foundSites) if ($sitesDoc.Length -gt 0) { $xmlDoc.DocumentElement.CreateNavigator().AppendChild($sitesDoc) } if ($global:certificateXML.Length -gt 0) { $xmlDoc.DocumentElement.CreateNavigator().AppendChild($global:certificateXML) } else { $tempdoc = "" $xmlDoc.DocumentElement.CreateNavigator().AppendChild($tempdoc) } if ($global:blockedPorts.Length -gt 0) { $xmlDoc.DocumentElement.CreateNavigator().AppendChild($global:blockedPorts) } } } # # End WorkFolders functions # # # ------------------ # FUNCTIONS - END # ------------------ # # ---------------------------------------- # SCRIPT MAIN BODY WORK FOLDERS - START # ----------------------------------------- # # # Initialize to perform querying Role information # Setup # # Set the Target Namespace to be used by XML # $tns="http://schemas.microsoft.com/bestpractices/models/FileServices/WorkFolders/2011/04" # # Create a new XmlDocument # $doc = Create-DocumentElement $tns "WorkFoldersComposite" $WorkFoldersInstalled = Check-FeatureInstallStatus "FS-SyncShareService" if($WorkFoldersInstalled) { GetWorkFoldersXml $doc $tns } # # Role Information obtained. # TearDown $doc