rzander / ruckzuck

software package manager for windows
https://ruckzuck.tools
Microsoft Public License
223 stars 20 forks source link

Automate App Update with Ruckzuck/SCCM/Powershell #56

Closed AnsgarGeers closed 5 years ago

AnsgarGeers commented 5 years ago

I Search for an Way, to automate the Update Process of existing Applications in SCCM. I have tried http://rzander.azurewebsites.net/update-existing-sccm-applications-with-ruckzuck/ but the Assembly seems to be changed.

Give it an actually description for that? mfg Ansgar Geers

rzander commented 5 years ago

The current version does not have that automation functionality: https://github.com/rzander/ruckzuck/issues/56 Can you share some informations why you want to update applications full unattended ? With the RZ4CM.exe it's only a few clicks...

AnsgarGeers commented 5 years ago

I want it to use, for Automated Update all Applicaions, Superseed old Application Version and create new Phased Device Collection Deployment with auto Update superseeded Applications. It will be used for an Server and Terminalserver enviroment. Not for User centric Deployment...

rzander commented 5 years ago

I have update the tool to allow automatic updates (extract the new EXE from the attached ZIP) RZ4CM.zip

Example to scan and enforce Updates:

#Import SCCM PowerShell Module
import-module (Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1)  
Set-Location ((Get-PSDrive -PSProvider CMSite).Name + ':')

#Load the RZ4ConfigMgr Assembly
[System.Reflection.Assembly]::LoadFrom((Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) RZ4CM.exe)) | Out-Null

$RZ = New-Object RuckZuck_Tool.PSRZ4ConfigMgr; 

#Scan for Updates
$RZ.Scan();

#List all Updates
$RZ.SWUpdates.ShortName

#get all Updates
$RZ.Update()

Note: This is a first draft, please provide feedback if it's working or not....

AnsgarGeers commented 5 years ago

Little bit Beta, but it Works, Phased Deployment are not Possible at this Moment over Powershell

Import SCCM PowerShell Module

import-module (Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1)
cd ((Get-PSDrive -PSProvider CMSite).Name + ':') $sitecode = (Get-PSDrive -PSProvider CMSite).Name

Ruckzuck Application Update

Load the RZ4ConfigMgr Assembly

[System.Reflection.Assembly]::LoadFrom((Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) RZ4CM.exe)) | Out-Null

$RZ = New-Object RuckZuck_Tool.PSRZ4ConfigMgr;

Scan for Updates

$RZ.Scan();

List all Updates

$RZ.SWUpdates.ShortName

get all Updates

$RZ.Update()

End RuckZuck Update

At this time there is a bug in the new RZ4CM.exe always create User Collections, this removes the Deployments and delete the User Collections

Delete User Collection

$UserCollections = Get-CMCollection -CollectionType User -Name UAI* Foreach ( $UserCollection in $USerCollections) { Get-CMDeployment -CollectionName $UserCollection.Name | Remove-CMDeployment -Force Remove-CMCollection -Name $UserCollection.Name -Force }

End Delete User Collection

Get all RuckZuck Apps

$CMRZAPPS = (Get-CMApplication | Where-Object LocalizedCategoryInstanceNames -eq {RuckZuck}) $RZapps = Get-WmiObject -Namespace root\SMS\site_$Sitecode -Class SMSApplicationlatest | Where-Object {$.ObjectPath -like "RuckZuck"}

End Get all RuckZuck Apps

foreach ($RZapp in $RZapps ){ if ( $RZapp.NumberOfDeployments -eq 0 ) { $RZapp.LocalizedDisplayName

    #Get only Ruckzuck Apps in Ruckzuck Folder not in Superseded Folder
    $CMRZapp = $CMRZAPPS | Where-Object { $_.LocalizedDisplayName -eq $RZapp.LocalizedDisplayName }

    # Get the short name of the applications for easier and safe comparison
    $CMRZAPPShortname = (($CMRZAPP).SDMPackageXML | Foreach { ([xml]$_).AppMgmtDigest.Application.CustomProperties.Property } | Where-Object { $_.Name -eq "Shortname" }).Value

    # Get all Old Version of Application only in Ruckzuck Folder
    $CMRZOLDAPPS = $CMRZAPPS | Where-object { ($_.SDMPackageXML `
                             | Foreach { ([xml]$_).AppMgmtDigest.Application.CustomProperties.Property } `
                             | Where-Object { $_.Name -eq "Shortname" }).Value -eq $CMRZAPPShortname `
                             -and $_.SoftwareVersion -lt $CMRZAPP.SoftwareVersion } `
                             | Where-object { $RZapps.LocalizedDisplayName -contains $_.LocalizedDisplayName }

    # Distribute the Application to all Groups
    Get-CMDistributionPointGroup | foreach { Start-CMContentDistribution -ApplicationName $CMRZapp.LocalizedDisplayName -DistributionPointGroupname $_.Name -ErrorAction SilentlyContinue -verbose | Out-Null }

    If(![String]::isnullorempty($CMRZOLDAPPS.LocalizedDisplayName)){
        $CMRZOLDAPPS | foreach { 
                                Write-Host "Old Deployment"        
                                $CMRZAPPOLDDep = get-cmdeployment -SoftwareName $_.LocalizedDisplayName
                                $Olddeptypes = Get-CMDeploymentType -ApplicationName $_.LocalizedDisplayName
                                $newdeptypes = Get-CMDeploymentType -ApplicationName $CMRZapp.LocalizedDisplayName

                                # Add superseded for Deployment Install_x64 and install_x86
                                Foreach( $oldDEPtype in $Olddeptypes) {
                                    foreach ( $newdeptype in $newdeptypes) {
                                        if( $oldDEPtype.LocalizedDisplayName -like $newdeptype.LocalizedDisplayName ) {
                                            Add-cmdeploymenttypesupersedence -SupersedingDeploymentType $newdeptype -SupersededDeploymentType $oldDEPtype -IsUninstall $true -Verbose
                                        }
                                    }
                                }
                                foreach ( $OLDDep in $CMRZAPPOLDDep ) {
                                # Copy the old to the new Application add 21 Days to the Deadline
                                New-CMApplicationDeployment -CollectionName $CMRZAPPOLDDep.Collectionname -DeployAction Install -EnableMomAlert $True -GenerateScomAlertOnFailure $True -UpdateSupersedence $true -EnableSoftDeadline $true -TimeBaseOn LocalTime -Name $RZapp.LocalizedDisplayName -UserNotification DisplaySoftwareCenterOnly -DeployPurpose Available -DeadlineDateTime (get-date).adddays(+21) -RebootOutsideServiceWindow $false -AvailableDateTime $(Get-date) -Verbose

                                # Correct the Deadline Bug for Superseded Deployment
                                $WMIFormat = New-Object -ComObject Wbemscripting.swbemdatetime
                                $DeadlineTime = [DateTime]::Today.AddDays(+21).AddHours(6)
                                $WMIFormat.SetVarDate($DeadlineTime,$true)
                                #Let's change now the value
                                $Deployment = Get-WmiObject -Namespace "root\SMS\site_$($sitecode)" -Class "SMS_ApplicationAssignment" | Where-Object { $_.ApplicationName -like $RZapp.LocalizedDisplayName -and $_.CollectionName -like $CMRZAPPOLDDep.Collectionname} 
                                $Deployment.UpdateDeadline = $WMIFormat.Value
                                $Deployment.Put()
                        }
                        #Remove old Deployment
                        Get-CMApplicationDeployment -Name $_.LocalizedDisplayName | Remove-CMApplicationDeployment -Force -verbose
                        $CMAPPLICATION  = Get-CMApplication -Name $_.LocalizedDisplayName

                        #Move to Superseded Folder
                        Move-CMObject -FolderPath "$($Sitecode):\Application\Supersedence" -inputobject $CMAPPLICATION -verbose
                  }

    }

    Else{
        Write-Host "New Deployment"
        New-CMApplicationDeployment -CollectionName "All Systems" -DeployAction Install -EnableMomAlert $True -GenerateScomAlertOnFailure $True -TimeBaseOn LocalTime -Name $RZapp.LocalizedDisplayName -UserNotification DisplaySoftwareCenterOnly -DeployPurpose Available -AvailableDateTime $(Get-date) -Verbose
    }
}          

}

prisme666 commented 2 years ago

for me to work, i must add this to script powershell :

active le TLS1.2

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Connect to MECM

import-module (Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1)
Set-Location ((Get-PSDrive -PSProvider CMSite).Name + ':')

Load the RZ4ConfigMgr Assembly

[System.Reflection.Assembly]::LoadFrom((Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) RZ4CM.exe)) | Out-Null # Start Ruckzuck start ((Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) RZ4CM.exe)) Start-Sleep 10 Stop-Process -Name "RZ4CM" $RZ = New-Object RuckZuck_Tool.PSRZ4ConfigMgr

Scan for Updates

$RZ.Scan()

List all Updates

$RZ.SWUpdates.ShortName | Out-file -Append $Logfile -Encoding UTF8

get all Updates

$RZ.Update() | Out-file -Append $Logfile -Encoding UTF8