AKN704634

Monitor_AKN704634 (UnitMonitor)

MD5 certificates prevents iOS mobile clients from signing in Lync

Element properties:

TargetMicrosoft.KnowledgeServices.Lync.2010.CsServer
Parent MonitorSystem.Health.ConfigurationState
CategoryAlert
EnabledTrue
Alert GenerateTrue
Alert SeverityError
Alert PriorityNormal
Alert Auto ResolveTrue
Monitor TypeMicrosoft.KnowledgeServices.Library.PowerShellMonitorEx
RemotableTrue
AccessibilityPublic
Alert Message
MD5 certificates prevents iOS mobile clients from signing in Lync
<Details>
<Content>System Center advisor detects that the Lync Server certificates are using MD5 algorithms. MD5 certificates are proved and recognized as non secure algorithm, iOS mobile devices are not accepting certificates signed with MD5 so that iOS Lync clients cannot sign in successfully. To fix the issue, see the following Microsoft Knowledge Base (KB) article for more information.</Content>
<CollectedInformation />
</Details>
RunAsMicrosoft.KnowledgeServices.ElevatedAccount
CommentSupportTopic=TBD;VersionNumber=1.0.0.0;

Source Code:

<UnitMonitor ID="Monitor_AKN704634" Comment="SupportTopic=TBD;VersionNumber=1.0.0.0;" Accessibility="Public" Enabled="true" Target="MicrosoftKnowledgeServicesLyncLibrary!Microsoft.KnowledgeServices.Lync.2010.CsServer" ParentMonitorID="Health!System.Health.ConfigurationState" Remotable="true" Priority="Normal" RunAs="KnowledgeServicesLibrary!Microsoft.KnowledgeServices.ElevatedAccount" TypeID="KnowledgeServicesLibrary!Microsoft.KnowledgeServices.Library.PowerShellMonitorEx" ConfirmDelivery="true">
<Category>Alert</Category>
<AlertSettings AlertMessage="MonitorMessagedfba8a100d334c20ad39d0178ad9cc8c">
<AlertOnState>Error</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>Error</AlertSeverity>
</AlertSettings>
<OperationalStates>
<OperationalState ID="Success" MonitorTypeStateID="Success" HealthState="Success"/>
<OperationalState ID="Error" MonitorTypeStateID="Error" HealthState="Error"/>
</OperationalStates>
<Configuration>
<ScriptName>AKN704634.ps1</ScriptName>
<Parameters/>
<ScriptBody><Script>
[ScriptBlock]$mainScriptBlock = {

$ErrorActionPreference = "Stop"

# Set up the arguments
$scriptargs = new-object psobject

# Set up the output
$global:scriptoutput = new-object psobject
$scriptoutput | add-member NoteProperty "HasIssue" $false
#-----------------------------------------------------
# Environment
#-----------------------------------------------------
$script:lyncPath = ""
if (Join-Path $Env:CommonProgramFiles "\Microsoft Lync Server 2013\Modules\Lync\Lync.psd1" | Test-Path)
{
$script:lyncPath = Join-Path $Env:CommonProgramFiles "\Microsoft Lync Server 2013\Modules\Lync\Lync.psd1"
$script:lyncPSVer = 2013
}
elseif (Join-Path $Env:CommonProgramFiles "\Microsoft Lync Server 2010\Modules\Lync\Lync.psd1" | Test-Path)
{
$script:lyncPath = Join-Path $Env:CommonProgramFiles "\Microsoft Lync Server 2010\Modules\Lync\Lync.psd1"
$script:lyncPSVer = 2010
}
$ScriptEnv = New-Object psobject
$ScriptEnv | Add-Member NoteProperty "RuntimeError" $false
$ScriptEnv | Add-Member NoteProperty "HasIssue" $false
$ScriptEnv | add-member ScriptMethod "ImportLyncPSModule" -value {
$m = Get-Module -Name Lync
if ($m -eq $null)
{
Import-Module $script:lyncPath -ErrorAction:SilentlyContinue
}
}
$ScriptEnv | Add-Member ScriptMethod "IsCMSMaster" -Value {
Try
{
$cmsStatus = Get-CsManagementStoreReplicationStatus -CentralManagementStoreStatus
$agentHostFqdn = [System.Net.Dns]::GetHostByName([System.Net.Dns]::GetHostName()).HostName
return $cmsStatus.ActiveMasterFqdn -ieq $agentHostFqdn
}
Catch [Microsoft.Rtc.Management.ADConnect.CannotGetDomainInfoException]
{
}
Catch [Microsoft.Rtc.Common.Data.SqlConnectionException]
{
}
Catch [System.Data.SqlClient.SqlException]
{
}
return $false
}

#-----------------------------------------------------
# MAIN CODE SECTION
#-----------------------------------------------------

function IsEdgeServer()
{
$result = $false;
$edgeServices = @(Get-Service | Where-Object { $_.DisplayName -like "*edge*" })
$result = $edgeServices.Count -gt 0
return $result
}

function IsFrontEndServer()
{
$result = $false
$edgeServices = @(Get-Service | Where-Object { $_.DisplayName -like "*edge*" })
if($edgeServices.Count -eq 0)
{
$agentHostFqdn = [System.Net.Dns]::GetHostByName([System.Net.Dns]::GetHostName()).HostName
$fes = @(Get-CsService -UserServer)
$pools = @(Get-CsPool)
foreach($pool in $pools)
{
$fePool = $fes | Where-Object { $_.PoolFqdn -ieq $pool.Identity }
if($fePool -ine $null)
{
if($pool.Computers -contains $agentHostFqdn)
{
$result = $true
break
}
}
}
}
return $result
}

function AdvisorRule($scriptargs, $scriptoutput)
{
trap [Exception]
{
$scriptenv.RuntimeError = $true
continue
}

$scriptenv.HasIssue = $false

if((IsFrontEndServer) -or (IsEdgeServer))
{
$scriptenv.ImportLyncPSModule()

$csCerts = @(Get-CsCertificate)
foreach($csCert in $csCerts)
{
$cert = Get-ChildItem -Path Cert: -Recurse | where { $_.Thumbprint -ieq $csCert.Thumbprint }
if ($cert -ne $null -and $cert.SignatureAlgorithm.FriendlyName -match "^MD5")
{
$scriptenv.HasIssue = $true
break
}
}
}

if($scriptenv.HasIssue -eq $true -and $scriptenv.RuntimeError -eq $false)
{
$scriptoutput.HasIssue = $true
}
}

AdvisorRule $scriptargs $scriptoutput

}

Function Test-NeedPSRemoting
{
$script:lyncPSVer = 0
if (Join-Path $Env:CommonProgramFiles "\Microsoft Lync Server 2013\Modules\Lync\Lync.psd1" | Test-Path)
{
$script:lyncPSVer = 2013
}
elseif (Join-Path $Env:CommonProgramFiles "\Microsoft Lync Server 2010\Modules\Lync\Lync.psd1" | Test-Path)
{
$script:lyncPSVer = 2010
}
$PSCLRVersion = [System.String]::Format("{0}.{1}", $PSVersionTable.CLRVersion.Major, $PSVersionTable.CLRVersion.Minor)
if (($PSCLRVersion -ieq "2.0") -and ($script:lyncPSVer -ieq 2013))
{
return $true
}
return $false
}

if ((Test-NeedPSRemoting))
{
[bool]$script:psRemotingEnabled = $false
# Enable PowerShell Remoting need elevated BUILTIN\Administrators privilege
$winRMService = (Get-Service WinRM -ErrorAction SilentlyContinue)
if ($winRMService -ne $null)
{
if ($winRMService.Status -ieq [System.ServiceProcess.ServiceControllerStatus]::Stopped)
{
$winRMService.Start()
$winRMService.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, [System.TimeSpan]::FromSeconds(15))
}
$psSessionConfiguration = (Get-PSSessionConfiguration -Name "Microsoft.PowerShell" -ErrorAction SilentlyContinue)
if ($psSessionConfiguration.Permission.Contains("BUILTIN\Administrators AccessAllowed"))
{
$script:psRemotingEnabled = $true
}
}

# Call remote PS session when PSRemoting is enabled.
if ($script:psRemotingEnabled -eq $true)
{
$session = New-PSSession
Invoke-Command -Session $session -ScriptBlock $mainScriptBlock
$global:scriptoutput = Invoke-Command -Session $session -ScriptBlock {$global:scriptoutput}
Remove-PSSession -Session $session
}
}
else
{
&amp; $mainScriptBlock
}

# set the output
$mom = new-object -comobject "MOM.ScriptAPI"
$bag = $mom.CreatePropertyBag()

if ($scriptoutput.HasIssue -ne $null)
{
$bag.AddValue("HasIssue", $scriptoutput.HasIssue)
}

$bag

</Script></ScriptBody>
<SnapIns/>
<TimeoutSeconds>300</TimeoutSeconds>
<Schedule>14400</Schedule>
<ErrorExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Boolean">Property[@Name='HasIssue']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</ErrorExpression>
<SuccessExpression>
<Not>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Boolean">Property[@Name='HasIssue']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</Not>
</SuccessExpression>
</Configuration>
</UnitMonitor>