cmdlets/Uninstall-1C.ps1

#09.2017©willynilly

. $PSScriptRoot\CommonUtils\CommonUtils.ps1

#----------------------------------------------------------------------------------------
# Запускает деинсталяцию установленных экземпляров 1С
function Uninstall-1C {
<#
    .SYNOPSIS
        Деинсталирует не используемые версии платформы 1С.
    .DESCRIPTION
        Деинсталирует все установленые стандартным установщиком версии платформы 1С кроме:
        - заданных по умолчанию в файле iBases.v8i из профиля текущего пользователя
        - запущенных на момент выполнения скрипта
        После запуска команды выводится список всех установленных платформ для удаления
        (список исключений выделен цветом) и ожидается подтверждение пользователя на удаление.
 
    .PARAMETER Force
        Выполнить деинсталяцию без вопросов пользвователю.
    .PARAMETER Wait
        Для завершения работы ждать подтверждения от пользователя.
#>
    
    [CmdletBinding()]

    param(
        [switch]$Wait, # Ожидать нажатия любой клавиши (параметр переключатель)
        [switch]$Force # молча выполнить без вопросов пользователю (параметр переключатель)
    )

    $DickUsedBefore = (Get-PSDrive -Name C).Used # занято на диске до начала деинсталяции
    $TotalWatch = [System.Diagnostics.Stopwatch]::StartNew() # глобальный секундомер
    $Watch = [System.Diagnostics.Stopwatch]::StartNew() # секундомер для операции

    $TotalWatch.Start() #Запуск глобального секундомера

    # получим список ислючений из удаления
    $Watch.Reset()
    $Watch.Start()
    $ExceptPlatform = Get-ExceptPlatform
    $Watch.Stop()
    $TimeGetExcept = $Watch.Elapsed

    # Получим все приложения вендора
    $Watch.Reset()
    $Watch.Start()
    $InstalledPlatform = Get-InstalledPlatform
    $Watch.Stop()
    $TimeGetting = $Watch.Elapsed
    
    # Покажем что получили
    $HasRemove = Show-ListToUninstall $InstalledPlatform $ExceptPlatform

    # Запрос на продолжение
    if (-not($Force))
    {
        $TotalWatch.Stop() #Тормознем глобальный секундомер (пропустим раздумья пользователя)
        $CanContinue = Get-Permission
        $TotalWatch.Start()
    }
    
    #Запустить деинсталяцию
    $DickFree = 0
    $Watch.Reset()
    if ($HasRemove -and $CanContinue)
    {
        $Watch.Start()
        Run-Uninstall $InstalledPlatform $ExceptPlatform
        $Watch.Stop()
        $DickFree = $DickUsedBefore - (Get-PSDrive -Name C).Used # высвобождено после деинсталяции
    }
    $TimeUninstall = $Watch.Elapsed
    
    #Подведем итоги работы
    ''
    $TotalWatch.Stop() #Остановка глобального секундомера
    $MaxRight = 50
    $MaxLeft = 12
    $Sym = '.'
    $TimeFormat = '{0:hh}:{0:mm}:{0:ss}.{0:fff}'
    ("Затрачено на получение списка установленных").PadRight($MaxRight,$Sym) + $TimeFormat -f $TimeGetting
    ("Затрачено на получение списка исключений").PadRight($MaxRight,$Sym) + $TimeFormat -f $TimeGetExcept
    
    ("Количество установленных экземпляров").PadRight($MaxRight,$Sym) + ('{0}' -f $InstalledPlatform.Count).PadLeft($MaxLeft, $Sym)
    ("Количество исключений").PadRight($MaxRight,$Sym) + ('{0}' -f $ExceptPlatform.Count).PadLeft($MaxLeft, $Sym)
    
    ("Затрачено на деинсталяцию").PadRight($MaxRight,$Sym) + $TimeFormat -f $TimeUninstall

    ("Всего высвобождено на диске").PadRight($MaxRight,$Sym) + ('{0:n3} Gb' -f ($DickFree/1Gb)).PadLeft($MaxLeft, $Sym)
    ("Всего затрачено:").PadRight($MaxRight,$Sym) + $TimeFormat -f $TotalWatch.Elapsed

    if ($Wait) { Wait-PressAnyKey }
        
}# end Uninstall-1C

#----------------------------------------------------------------------------------------
# Удаляет платформы из переданного списка установленных кроме списка исключений если задан
function Run-Uninstall($InstalledPlatform, $ExceptPlatform = $null)
{
    Write-Host "`nУдаленные:"
    foreach($Platform in $InstalledPlatform)
    {
        if (Can-UninstallVersion $Platform.Version $ExceptPlatform)
        {
            Write-Host (" {0}" -f $Platform.Name) -ForegroundColor Green
            $Platform.Uninstall() | Out-Null
        }
    }
        
}# end Run-Uninstall

#----------------------------------------------------------------------------------------
# Показывает список к удалению но не удаляет
function Show-ListToUninstall($InstalledPlatform, $ExceptPlatform = $null)
{
    Write-Host "`nСписок к удалению:"
    $HasRemove = $false
    foreach($Platform in $InstalledPlatform)
    {
        if (Can-UninstallVersion $Platform.Version $ExceptPlatform)
        {
            Write-Host (" {0}" -f $Platform.Name) -ForegroundColor Green
            $HasRemove = $true
        }
        else
            {Write-Host (" {0}" -f $Platform.Name) -ForegroundColor Yellow}
    }
    return $HasRemove
        
}# end Show-ListToUninstall

#----------------------------------------------------------------------------------------
# Проверяет возможность удаления
function Can-UninstallVersion($Version, $ExceptPlatform = $null)
{
    $Results = $True
    if ($ExceptPlatform -ne $null)
    { 
        $Results = -not($ExceptPlatform.ContainsKey($Platform.Version))
    }

    return $Results
        
}# end Can-UninstallVersion

#----------------------------------------------------------------------------------------
# получает версии установленных платформ
function Get-InstalledPlatform
{
    $VendorEN = "1C"
    $VendorRU = "1С"

    $FilterVendor = "(Vendor like '{0}%' or Vendor like '{1}%')" -f $VendorEN, $VendorRU
    $FilterName = "(Name like '{0}%' or Name like '{1}%')" -f ($VendorEN + ":Предприятие"), ($VendorRU + ":Предприятие")
    $Filter = "{0} and {1}" -f $FilterVendor, $FilterName
    $InstalledPlatform = Get-WmiObject -Class Win32_Product -Filter $Filter -ComputerName "." | Sort-Object Version, Name

    return $InstalledPlatform
        
}# end Get-InstalledPlatform

#----------------------------------------------------------------------------------------
# получает версии платформ запрещенных для удаления
function Get-ExceptPlatform
{
    # соберем все что удалять не надо
    Write-Host "`nСписок исключений для удаления получен:"
    $ExceptPlatform = @{}
    Add-1CEStart_cfg $ExceptPlatform
    Add-StartedProcess1C $ExceptPlatform
    Write-Host ''
    $ExceptPlatform.Keys | sort | foreach{Write-Host(' {0}' -f $_) -ForegroundColor Yellow}

    return $ExceptPlatform
        
}# end Get-ExceptPlatform

#----------------------------------------------------------------------------------------
# добавляет версии платформ перечисленные в файле 1CEStart.cfg из профиля пользователя
function Add-1CEStart_cfg($ExceptPlatform)
{
    $Ok = $false
    $fpathEStartCfg = $env:appdata + "\1C\1CEStart\1CEStart.cfg"
    if(Test-Path $fpathEStartCfg) {
       Get-Content $fpathEStartCfg | where {$_ -match 'DefaultVersion'} | 
            foreach {
                $Platform = ($_ -split '-')[1]
                $Platform = ($Platform -split ';')[0]
                $ExceptPlatform[$Platform]=""; $Ok = $true
            }
       if ($Ok){Write-Host (" - из файла {0}" -f $fpathEStartCfg)}
    }

}# end Add-1CEStart_cfg

#----------------------------------------------------------------------------------------
# добавляет версии платформ всех запущенных в текущий момент процессов
function Add-StartedProcess1C($ExceptPlatform)
{
    $Ok = $false
    Get-Process "1cv8*" -FileVersionInfo | foreach{$ExceptPlatform[$_.FileVersion]=""; $Ok = $true}
    Get-Process "ragent*" -FileVersionInfo | foreach{$ExceptPlatform[$_.FileVersion]=""; $Ok = $true}
    if ($Ok){Write-Host " - из списка запущеных процессов"}
        
}# end Add-StartedProcess1C