แชแแขแ แฎแแแก แฌแแ แฉแแแ แแแแแฎแแแ แแแแแแแแ, แแแแแแแแ แแแ แกแแ แแแคแแแแขแแแแก แแแฅแแแแแแแก แแแ แแแแก Windows แกแแ แแแ แแแแ. แแแ, แ แแแแ แแแแแฅแ แแแก แจแแแแแ, แ แแช แกแแ แแแคแแแแขแแแ แ แแแแแแฏแแ แแ แแแแ แแ แแฅแชแ, แกแฌแแ แแ แแ แแ แแก, แ แแชแ แแแ แแแแแฎแแแแแแ แแแกแฃแฎแแกแแแแแแแ แฌแแแ แแแแ แแแแแแ แจแแแแฃแแแแแจแ แแงแ. แแแแก แจแแแแแ แแ แแ แแแก แ แแฆแแช แแแญแแแแแแแแแ แแ แแแแแแฌแงแแแขแแ แแแแแ แแแแคแแฅแ แ. แแแแแแแแ แฉแแแ แแแ-แแแแ แแแฎแแ แชแแแแแแ NetXMS แแแแแขแแ แแแแแก แกแแกแขแแแแก, แแก แแแฎแแ แแ แแแแชแแแแก แแแแแแ แ แแ แแ แแแชแแแจแ แแ แแแแแ แแ แแแแแแแแขแ.
แจแแแแแ แกแแแแแแแ แแแแฆแแก แจแแแแแ แคแแ แแแจแ:
แแ แแแแแ แแ แแชแแกแ แแ แซแแแแแแ.
แฌแแแ. NetXMS-แจแ แแ แแ แแก แฉแแจแแแแแฃแแ แแ แแชแฎแแแแ แแแแแแแกแฃแแ แกแแ แแแคแแแแขแแแแกแแแแก, แแกแ แ แแ แแฅแแแ แฃแแแ แจแแฅแแแแ แแฅแแแแ แกแแแฃแแแ แ แแ แแแแแแงแแแแ แกแแ แแแขแแแ แแแกแ แแแแแชแแแแแแก แแแกแแฌแแแแแแแ. แ แ แแฅแแ แฃแแแ, Powershell-แแ แแก แแ แแก Windows. แกแแ แแแขแแ แฃแแแ แฌแแแแแแฎแแก แแแแ แแชแแฃแแ แกแแกแขแแแแก แงแแแแ แกแแ แแแคแแแแขแ, แแแฆแแก แแแแ แแแ แแแกแแแแแแแก แแแแ แแฆแแแแจแ แแ แแแแแกแชแแก แแก แแแแแ แ NetXMS-แก. แแแกแ แแแแแขแแก แแแจแแแแแแ. แกแฌแแ แแ แแฅแแแแ แแแแแฌแงแแแ.
แแแ แแแแขแ แแ แแ, แฃแแแ แขแแแแกแ. แฃแแ แแแแ แแแแฆแแ แแฆแแแแแก แ แแแแแแแแ แกแแ แขแแคแแแแขแแก แแแแแก แแแกแแแแแแ แฃแแฎแแแแกแ แแแ แแฆแแ.
แแแแกแแแแแก, แ แแ NetXMS แกแแ แแแ แแ แแชแแแแก แฉแแแแ แแแ แแแแฃแแ แแแ แแแแขแ แแก แแ แกแแแแแแก แจแแกแแฎแแ, แแแ แแก แฃแแแ แแแแฆแแก แแแแแขแแกแแแ. แฌแแแแแฆแแแแ แจแแแแฎแแแแแจแ, แแ แแแ แแแแขแ แแก แแแแแขแแแ แจแแฃแซแแแแแแแ แแแกแ แแ แแ แกแแแแแแก แแแแ. แแแแขแแ, แแแแแขแแก แแแแคแแแฃแ แแชแแแก แคแแแแจแ nxagentd.conf แฉแแแ แแแแแขแแแ แแแ แ แแแ แแแแขแ แแก แกแขแ แแฅแแแก, แ แแแแแกแแช แ.แฌ HTTPS.CertificateExpireDateSimple, แ แแแแแจแแช แฉแแแ แแแ แแแแกแขแ แแ แแแ แกแแ แแแขแแก แแแจแแแแแก:
ExternalParameter = HTTPS.CertificateExpireDateSimple: powershell.exe -File "servershareNetXMS_CertExpireDateSimple.ps1"
แแแแก แแแแแแแแกแฌแแแแแแ, แ แแ แกแแ แแแขแ แแแจแแแแฃแแแ แฅแกแแแจแ, แแฅแแแ แฃแแแ แแแฎแกแแแแแ แแแแก แจแแกแแฎแแ
แจแแแแแแ, แแแแแขแแก แแแแคแแแฃแ แแชแแ แแกแ แแแแแแงแฃแ แแแ:
#
# NetXMS agent configuration file
# Created by agent installer at Thu Jun 13 11:24:43 2019
#
MasterServers = netxms.corp.testcompany.ru
ConfigIncludeDir = C:NetXMSetcnxagentd.conf.d
LogFile = {syslog}
FileStore = C:NetXMSvar
SubAgent = ecs.nsm
SubAgent = filemgr.nsm
SubAgent = ping.nsm
SubAgent = logwatch.nsm
SubAgent = portcheck.nsm
SubAgent = winperf.nsm
SubAgent = wmi.nsm
ExternalParameter = HTTPS.CertificateExpireDateSimple: powershell.exe -File "servershareNetXMS_CertExpireDateSimple.ps1"
แแแแก แจแแแแแ, แแฅแแแ แฃแแแ แจแแแแแฎแแ แแแแคแแแฃแ แแชแแ แแ แแแแแขแแแ แแแ แแแแแขแ. แแแแก แแแแแแแแ แจแแแแซแแแแ NetXMS แแแแกแแแแแแ: แแแฎแกแแแแ แแแแคแแแฃแ แแชแแ (Edit agent's configuration file), แแแแ แแแแฅแขแแ แแ, แจแแแกแ แฃแแแ Save&Apply, แ แแก แจแแแแแแแแช, แคแแฅแขแแแ แแแแ, แแแแแ แแแฎแแแแ. แจแแแแแ แฎแแแแฎแแ แฌแแแแแแฎแแ แแแแคแแแฃแ แแชแแ (แแแแแแแแฎแแ > แแแแคแแแฃแ แแชแแ), แแฃ แแแแแแแก แซแแแ แกแแแ แแแ แแ แแแฅแแ. แแ แแแแแฏแแแแก แจแแแแแ, แแฅแแแ แฃแแแ แจแแซแแแ แฉแแแแ แแแ แแแแฃแแ แแแ แแแแขแ แแก แแแแแขแแแ.
NetXMS แแแแกแแแจแ แแแแแแแ แแแแแชแแแแ แจแแแ แแแแแแก แแแแคแแแฃแ แแชแแ แแฅแกแแแ แแแแแขแฃแแ แกแแ แแแ แ, แ แแแแแแแช แแแแแ แแแ แกแแ แแแคแแแแขแแแแก แแแแแขแแ แแแแก แแ แแฅ แแฎแแแ แแแ แแแแขแ แแก แจแแฅแแแแก (แแแแแแแแจแ, แแแแคแแแฃแ แแชแแแก แจแแแแแ, แแแ แ แแฅแแก แจแแแแแแแแแ แแแแแขแแแแก). แแแ แฉแแแ HTTPS.CertificateExpireDateSimple แกแแแแแ, แจแแแงแแแแแ แแฆแฌแแ แ แแแแคแแ แกแแฎแแแแ, แแแแงแแแแ แขแแแ แแแแ แ แแชแฎแแแ แแ แแแแแแแคแแแฃแ แแ แแ แแแแญแแกแงแ แแก แแแขแแ แแแแ. แแแแแ แแแแก แแแแแแ, แแแ แ แแฅแแก, แ แแ แแก แฃแคแ แ แแแแแ แแงแแก, แแแแแแแแแ, 30 แฌแแแ. แงแแแแแคแแ แ แแแแแแ, แฏแแ แกแแแแแ แแกแแ.
แจแแแแซแแแแ แจแแแแแฌแแแ... แแ แ, แฏแแ แแแ แแ. แแฎแแ, แ แ แแฅแแ แฃแแแ, แแแ แแคแแ แก แแแแแฆแแแ. แฃแแ แแแแ แแแแขแแ, แ แแ แกแชแแแแ แ แฏแแ แแ แแแฌแแ แแแ. แแแแแแแกแฌแแ แแ แแก แแแแแขแแแแแ. แกแแ แแแขแ แฃแแ แแแแ แแฉแแแแแแก แ แแชแฎแแก, แกแแ แแแคแแแแขแแก แแแแแก แแแแฌแฃแ แแแแแ แแแ แฉแแแแแ แแฆแแแแแก แ แแแแแแแแแก. แงแแแแแแ แแแแแแแแฃแ แ แงแแแแ แฎแแแแแกแแฌแแแแแ. แกแแ แแแขแแก แแแแแแแแ:
try {
# ะะพะปััะฐะตะผ ะฒัะต ัะตััะธัะธะบะฐัั ะธะท ั
ัะฐะฝะธะปะธัะฐ ัะตััะธัะธะบะฐัะพะฒ
$lmCertificates = @( Get-ChildItem -Recurse -path 'Cert:LocalMachineMy' -ErrorAction Stop )
# ะัะปะธ ัะตััะธัะธะบะฐัะพะฒ ะฝะตั, ะฒะตัะฝััั "10 ะปะตั"
if ($lmCertificates.Count -eq 0) { return 3650 }
# ะะพะปััะฐะตะผ Expiration Date ะฒัะตั
ัะตััะธัะธะบะฐัะพะฒ
$expirationDates = @( $lmCertificates | ForEach-Object { return $_.NotAfter } )
# ะะพะปััะฐะตะผ ะฝะฐะธะฑะพะปะตะต ะฑะปะธะทะบะธะน Expiration Date ะธะท ะฒัะตั
$minExpirationDate = ($expirationDates | Measure-Object -Minimum -ErrorAction Stop ).Minimum
# ะะพะฝะฒะตััะธััะตะผ ะฝะฐะธะฑะพะปะตะต ะฑะปะธะทะบะธะน Expiration Date ะฒ ะบะพะปะธัะตััะฒะพ ะพััะฐะฒัะธั
ัั ะดะฝะตะน ั ะพะบััะณะปะตะฝะธะตะผ ะฒ ะผะตะฝัััั ััะพัะพะฝั
$daysLeft = [Math]::Floor( ($minExpirationDate - [DateTime]::Now).TotalDays )
# ะะพะทะฒัะฐัะฐะตะผ ะทะฝะฐัะตะฝะธะต
return $daysLeft
}
catch {
return -1
}
แแกแ แแแแแแแก:
แกแแ แขแแคแแแแขแแก แแแแแก แแแแฌแฃแ แแแแแ แแแ แฉแ 723 แแฆแ, แแแแฅแแแก แแ แ แฌแแแ. แแแแแแฃแ แแ, แ แแแแแ แชแแขแ แฎแแแก แฌแแ แฎแแแแฎแแ แแแแชแ แกแแ แแแคแแแแขแแแ Exchange แขแแกแขแแก แกแแแแแกแแแแก.
แแแ แขแแแ แแแ แแแแขแ แแงแ. แแแแแ, แแแแแ แแแแ แแแแแแงแแคแแแแแแ, แแแแ แแ แแแขแ แแแแแแแแ. แฉแแแ แแแแแแแแแ, แ แแ แแแแแแแแแ แกแแ แแแ แแ แแ แกแแแฃแแ แงแแแแ แกแแ แแแคแแแแขแแก แกแแ, แกแแฎแแแแก แแแฎแแแแแ แแ แแแแแแฃแแแ แแแแฎแแ แกแแ แแแคแแแแขแแก แแแแแก แแแแฌแฃแ แแแแแ แแแ แฉแแแแแ แแฆแแแแแก แ แแแแแแแแ.
แแแแ แ แแแ แแแแขแ, แแแ แแแแฃแแฌแแแแ แฃแคแ แ แ แแฃแแ.
แฉแแแ แแแแแ แแแกแฌแแ แแแ แแแแแขแแก แแแแคแแแฃแ แแชแแแก แแ แแฅ, ExternalParameter-แแก แฎแแแแก แแแชแแแแ, แแฌแแ แ แแ แกแฎแแแก:
ExternalList = HTTPS.CertificateNames: powershell.exe -File "serversharenetxms_CertExternalNames.ps1"
ExternalParameter = HTTPS.CertificateExpireDate(*): powershell.exe -File "serversharenetxms_CertExternalParameter.ps1" -CertificateId "$1"
ะ แแแ แ แกแแ แฉแแแ แฃแแ แแแแ แแแฆแแแ แกแขแ แแฅแแแแแแก แฉแแแแแแแแแแก. แฉแแแแก แจแแแแฎแแแแแจแ, แกแขแ แแฅแแแแแแก แกแแ แกแแ แขแแคแแแแขแแแแก แกแแฎแแแแแแ. แฉแแแ แแแแแฆแแแ แแ แฎแแแแแแก แฉแแแแแแแแแแก แกแแ แแแขแแก แแแแแงแแแแแแ. แกแแแก แกแแฎแแแ - HTTPS.CertificateNames.
แกแแ แแแขแ NetXMS_CertNames.ps1:
#ะกะฟะธัะพะบ ะฒะพะทะผะพะถะฝัั
ะธะผะตะฝ ัะตััะธัะธะบะฐัะพะฒ
$nameTypeList = @(
[System.Security.Cryptography.X509Certificates.X509NameType]::SimpleName,
[System.Security.Cryptography.X509Certificates.X509NameType]::DnsName,
[System.Security.Cryptography.X509Certificates.X509NameType]::DnsFromAlternativeName,
[System.Security.Cryptography.X509Certificates.X509NameType]::UrlName,
[System.Security.Cryptography.X509Certificates.X509NameType]::EmailName,
[System.Security.Cryptography.X509Certificates.X509NameType]::UpnName
)
#ะัะตะผ ะฒัะต ัะตััะธัะธะบะฐัั, ะธะผะตััะธะต ะทะฐะบััััะน ะบะปัั
$certList = @( Get-ChildItem -Path 'Cert:LocalMachineMy' | Where-Object { $_.HasPrivateKey -eq $true } )
#ะัะพั
ะพะดะธะผ ะฟะพ ัะฟะธัะบั ัะตััะธัะธะบะฐัะพะฒ, ัะพัะผะธััะตะผ ัััะพะบั "ะะผั ัะตััะธัะธะบะฐัะฐ - ะะฐัะฐ - Thumbprint" ะธ ะฒะพะทะฒัะฐัะฐะตะผ ะตั
foreach ($cert in $certList) {
$name = '(unknown name)'
try {
$thumbprint = $cert.Thumbprint
$dateExpire = $cert.NotAfter
foreach ($nameType in $nameTypeList) {
$name_temp = $cert.GetNameInfo( $nameType, $false)
if ($name_temp -ne $null -and $name_temp -ne '') {
$name = $name_temp;
break;
}
}
Write-Output "$($name) - $($dateExpire.ToString('dd.MM.yyyy')) - [T:$($thumbprint)]"
}
catch {
Write-Error -Message "Error processing certificate list: $($_.Exception.Message)"
}
}
แแ แฃแแแ แจแแแแแ แแแ แ แแแ แแแแขแ แ แฉแแแ แจแแแแงแแแแ แ แแแแแก ExternalList แกแแแแแ แแ แแแแแกแแแแแแ แแแฆแแแ แแฆแแแแแก แแ แแกแ แแ แแแแแ แ แแแแแแแแแก แแแแแแฃแแแกแแแแก. แแแแแขแแคแแแแขแแ แ แแ แแก แกแแ แขแแคแแแแขแแก แชแแ แ แแแแแแญแแ. แแแแแแแแแกแฌแแแแ, แ แแ HTTPS.CertificateExpireDate แจแแแชแแแก แแแ แกแแแแแแก (*) แแ แแแ แแแแขแจแ. แแก แแฃแชแแแแแแแแ แแแแกแแแแแก, แ แแ แแแ แแแแฆแแก แแแ แ แชแแแแแแแ, แแฎแแแแ แฉแแแแ CertificateId.
แกแแ แแแขแ NetXMS_CertExpireDate.ps1:
#ะะฟัะตะดะตะปัะตะผ ะฒั
ะพะดััะธะน ะฟะฐัะฐะผะตัั $CertificateId
param (
[Parameter(Mandatory=$false)]
[String]$CertificateId
)
#ะัะพะฒะตัะบะฐ ะฝะฐ ัััะตััะฒะพะฒะฐะฝะธะต
if ($CertificateId -eq $null) {
Write-Error -Message "CertificateID parameter is required!"
return
}
#ะะพ Thumbprint ะธะท ัััะพะบะธ ะฒ $CertificateId ะธัะตะผ ัะตััะธัะธะบะฐั ะธ ะพะฟัะตะดะตะปัะตะผ ะตะณะพ Expiration Date
$certId = $CertificateId;
try {
if ($certId -match '^.*[T:(?<Thumbprint>[A-Z0-9]+)]$') {
$thumbprint = $Matches['Thumbprint']
$certificatePath = "Cert:LocalMachineMy$($thumbprint)"
if (Test-Path -PathType Leaf -Path $certificatePath ) {
$certificate = Get-Item -Path $certificatePath;
$certificateExpirationDate = $certificate.NotAfter
$certificateDayToLive = [Math]::Floor( ($certificateExpirationDate - [DateTime]::Now).TotalDays )
Write-Output "$($certificateDayToLive)";
}
else {
Write-Error -Message "No certificate matching this thumbprint found on this server $($certId)"
}
}
else {
Write-Error -Message "CertificateID provided in wrong format. Must be FriendlyName [T:<thumbprint>]"
}
}
catch {
Write-Error -Message "Error while executing script: $($_.Exception.Message)"
}
แกแแ แแแ แแก แแแแแชแแแแ แจแแแ แแแแแแก แแแแคแแแฃแ แแชแแแจแ แฉแแแ แแฅแแแแ แแฎแแ แแแ แแแแขแ แก. แแแ แแแแขแ แจแ แแแ แฉแแแ แฉแแแแก HTTPS.CertificateExpireDate(*) แกแแแแแ แแ (แงแฃแ แแแฆแแแ!) แจแแชแแแแแ แแแ แกแแแแแแ {แแแแแแแแ}. แแก แแแแจแแแแแแแแแ แฌแแ แขแแแ แกแแจแฃแแแแแแก แแแแชแแแ แจแแฅแแแแ แชแแแแ แแ แแชแฎแแแแ แแแแแแฃแแ แแแกแขแแแชแแแกแแแแก (แกแแ แแแคแแแแขแ). แแแแแ แฉแแแ แแแกแแแ แ แแแแ แช แฌแแแ แแแ แกแแแจแ:
แแแแกแแแแก, แ แแ แแฅแแแแแ แแ แแชแฎแแแแแแแก แจแแฅแแแ, Instance Discovery แฉแแแแ แแแ แแฅแแแ แฃแแแ แแแ แฉแแแ Agent List แกแแแแแ แแ List Name แแแแจแ แจแแแงแแแแแ แฉแแแแ ExternalList-แแก แกแแฎแแแ แกแแ แแแขแแแแ - HTTPS.CertificateNames.
แแแแฅแแแก แแแแแแ, แแแแชแแแ แชแแขแ แแ แแแซแฃแแ แแแแแแแแฎแแ > แแแแคแแแฃแ แแชแแ แแ แแแแแแแแฎแแ > แแแกแขแแแชแแแก แแฆแแแฉแแแ, แแฃ แแแแแแ แกแ แฃแแแแ แจแแฃแซแแแแแแแ. แจแแแแแแ, แฉแแแ แแแฆแแแ แงแแแแ แฉแแแแก แกแแ แขแแคแแแแขแก แแแฅแแแแแแแก แแแแแ:
แฒ แ แแญแแ แแแแ? แฐแแแ, แแฎแแแแ แแแ แคแแฅแชแแแแแแแแก แญแแ แกแแแแแแแ แแแแแแแแ แฃแงแฃแ แแแก แแแฎแแแก แกแแฎแแแแ แแ แแแแแแข แชแแ แก แแ แแ แแแซแแแแก แกแขแแขแแแก แแแกแ แฃแแแแแก. แแแก แจแแกแแแแฎแแ แแแแแ แแแฎแกแแแแ แแ แแชแฎแแแแแก แแแแกแแแแแ แแ Instance Discovery แฉแแแแ แแแ โแแแกแขแแแชแแแก แแฆแแแฉแแแแก แคแแแขแ แแก แกแแ แแแขแแกโ แแแแจแ แแแแแแขแแ
instance = $1;
if (instance ~= "^(.*)s-s[T:[a-zA-Z0-9]+]$")
{
return %(true, instance, $1);
}
return true;
แ แแแแแแช แแแคแแแขแ แแแก แแแแแก แแแแแแญแแก:
แแ แแแคแแแขแ แฃแแ แกแแฉแแแแแแแแ, แแฆแฌแแ แแแแแแก แแแแจแ แแแแแแ แฉแแแแ แแแ แจแแชแแแแแ CertificateExpireDate: {instance} Certificate ExpireDate: {instance-name}:
แแกแ แแแ, แกแแแแแแแ แแแกแ แฃแแแแ KDPV-แแแ:
แกแแแแแแแ แแ แแ?
แ แฉแแแ แแฎแแแแ แจแแขแงแแแแแแแแแแก แแแงแแแแแ แแกแ, แ แแ แแกแแแ แแแแแแแแ แแแแฅแขแ แแแฃแแ แคแแกแขแแ, แ แแแแกแแช แกแแ แขแแคแแแแขแ แแแแแฌแฃแ แแแ.
1. แแแ แแแ แ แแแจแ, แฉแแแ แฃแแแ แจแแแฅแแแแ Event Template, แ แแแ แแแแแแฅแขแแฃแ แแ แแก, แ แแแแกแแช แแ แแชแฎแแแแแก แแแแจแแแแแแแ แแชแแ แแแแ แฉแแแแก แแแแ แแแงแแแแแฃแ แแฆแแ แแแแ. IN แฆแแแแกแซแแแแแก แแแแคแแแฃแ แแชแแ แแแแแ แจแแแฅแแแแ แแ แ แแฎแแแ แจแแแแแแ แแกแแแแกแ แกแแฎแแแแแแ CertificateExpireDate_Threshold_Activate แแแคแ แแฎแแแแแแก แกแขแแขแฃแกแแ:
แแ แแกแแแแกแ CertificateExpireDate_Threshold_Deactivate แแแ แแแแฃแ แ แกแขแแขแฃแกแแ.
2. แจแแแแแ แแแแแแแ แแ แแชแฎแแแแแก แแแแกแแแแแแ แแ แแแแงแแแแ แแแ แแแ แ Tresholds แฉแแแแ แแแ:
แกแแแแช แฉแแแ แแแ แฉแแแ แฉแแแแก แแแแ แจแแฅแแแแ แแแแแแแแแก CertificateExpireDate_Threshold_Activate แแ CertificateExpireDate_Threshold_Deactivate, แแแงแแแแแ แแแแฃแจแแแแก แ แแแแแแแแแก (แแแแฃแจแแแ) 1-แแ (แแแแแ แแขแฃแแแ แแ แแ แแชแฎแแแแแกแแแแก แแแ แ แแ แแฅแแก แแแขแแก แแแงแแแแแแก), แแแแจแแแแแแแ แแ แแก 30 (แแฆแ), แแแแแแแแแ, แแ, แ แแช แแแแแแ แแ, แแแแงแแแแ แฆแแแแกแซแแแแแก แแแแแแแ แแแแก แแ แ. แฌแแ แแแแแแจแ แกแแ แแแคแแแแขแแแแกแแแแก, แแ แแแแแงแแแ แแแ แแฆแแจแ แแ แแฎแแ (86400 แฌแแแ), แฌแแแแแฆแแแแ แจแแแแฎแแแแแจแ แจแแแแซแแแแ แแแแฎแ แฉแแ แจแแขแงแแแแแแแแแจแ (แ แแช, แกแฎแแแแ แจแแ แแก, แแ แแฎแแ แแแฎแแ, แแแแแแแ, แ แแ แกแแคแแกแขแ แงแฃแแ แกแแแกแ แแงแ แจแแแแ-แแแแ แแก). แแแแแ แแแแก แแ แแก, แแแ แ แแฅแแก แแแงแแแแแก แฃแคแ แ แแแแแแ, แแแแแแแแแ, 60 แฌแแแ.
3. In แแแฅแแแแแแแก แแแแคแแแฃแ แแชแแ แจแแฅแแแแแ แจแแขแงแแแแแแแแก แฌแแ แแแแก แจแแแแแแ, แ แแแแ แแชแแ:
แงแแแแ แแก %m, %S แแ แ.แจ. - แแแแ แแแแ, แ แแแแแแจแแช แจแแแชแแแแแ แฉแแแแ แแแ แแแแขแ แแก แแแแจแแแแแแแแแ. แแกแแแ แฃแคแ แ แแแขแแแฃแ แแ แแ แแก แแฆแฌแแ แแแ
4. แแ แแแแแก, แฌแแแ แแฃแแฅแขแแแแก แแแแ แแแแแแแ, แจแแแแแ แฆแแแแกแซแแแแแก แแแแฃแจแแแแแแก แแแแแขแแแ แจแแฅแแแแแ แฌแแกแ, แ แแแแแก แแแฎแแแแแแแช แจแแแฅแแแแแ แกแแแแแแแแแชแแ แแ แแแแแแแแแแแ แฌแแ แแแ:
แฉแแแ แแแแแแแ แแแแแขแแแแก, แงแแแแแคแ แแก แจแแแแฌแแแแ แจแแกแแซแแแแแแแ. แแแแแ แแแแแงแแแแ แแแ แแแ แ แฃแคแ แ แแแฆแแแ แจแแกแแแแฌแแแแแแ. แฉแแแก แฃแแฎแแแแก แกแแ แขแแคแแแแขแก แแแแ แแฌแฃแ แแแ 723 แแฆแแจแ, แจแแแแแแฌแแแ 724-แแ. แจแแแแแแ แแแฆแแแ แจแแแแแ แกแแแแแแแแแชแแแก:
แแ แแก แแแคแแกแขแแก แจแแขแงแแแแแแแ:
แแก แงแแแแแคแแ แ แแฎแแ แแแ แฌแแฃแแแแฃแแแ. แ แ แแฅแแ แฃแแแ, แจแแกแแซแแแแแแ แแฅแแแแแแ แแแคแแก แแแงแแแแแ แแ แแ แแคแแแแแแก แแแแแ, แแแแ แแ แกแแ แแแคแแแแขแแแแกแแแแก แแก แแฅแแแแ แแแ แแแแฃแแฌแแแแ แฃแแแ แ แแ แแแกแแฌแงแแแ แกแฌแแ แ แฎแแแแแ, แแแแกแฎแแแแแแแ แแ แแชแแกแแ แแก แแ แแแฎแกแแแ แแแแก แแแขแแแ แแแแก แแ แแคแแแแแแกแแแ, แแแแแแแแแ. แแแแ แแ แแแแก แจแแกแแฎแแ แกแฎแแ แแ แแก.
แฌแงแแ แ: www.habr.com