diff --git a/functions/functions/Get-ChocoOutdatedPackages.ps1 b/functions/functions/Get-ChocoOutdatedPackages.ps1 new file mode 100644 index 0000000..80a6d87 --- /dev/null +++ b/functions/functions/Get-ChocoOutdatedPackages.ps1 @@ -0,0 +1,38 @@ +<# +.SYNOPSIS + Short description +.DESCRIPTION + Long description +.EXAMPLE + Example of how to use this cmdlet +.EXAMPLE + Another example of how to use this cmdlet +#> +function Get-ChocoOutdatedPackages { + [CmdletBinding()] + param( + ) + Write-Verbose "Getting local outdated packages" + $OutdatedPackages = (choco outdated -r --ignore-pinned --ignore-unfound --timeout=60) + if ($LASTEXITCODE -eq 1){ + Write-Verbose -Message 'Error getting outdated packages' + $OutdatedPackages + Exit + } + #If no updated packages are available then exit + if ($LASTEXITCODE -eq 0){ + Write-Verbose -Message 'No new packages available. Exiting' + Exit + } + else { + # $NewPackages = + foreach ($NewPackage in $OutdatedPackages){ + [PSCustomObject]@{ + Name = $NewPackage.Split('|')[0] + CurrentVersion = $NewPackage.Split('|')[1] + Version = $NewPackage.Split('|')[2] + Pinned = $NewPackage.Split('|')[3] + } + } + } +} \ No newline at end of file diff --git a/functions/functions/Get-ChocoPackageMetaData.ps1 b/functions/functions/Get-ChocoPackageMetaData.ps1 new file mode 100644 index 0000000..43246c3 --- /dev/null +++ b/functions/functions/Get-ChocoPackageMetaData.ps1 @@ -0,0 +1,45 @@ +Function Get-ChocoPackageMetaData { + <# + .SYNOPSIS + Return package metadata from a given Chocolatey Package(s) + + .DESCRIPTION + Reads the contents of the nupkg and extracts metadata from the nuspec contained within it + + .PARAMETER ChocolateyPackage + The chocolatey package(s) you wish to extract data from + + .EXAMPLE + Get-ChocoPackageMetaData -ChocolateyPackage C:\Packages\googlechrome.nupkg + + .NOTES + Written by Stephen Valdinger of Chocolatey Software for Dan Franciscus + #> + + [cmdletBinding()] + Param( + [ValidateScript({Test-Path $_})] + [String[]] + $ChocolateyPackage + ) + + begin { $null = Add-Type -Assemblyname "System.IO.Compression.Filesystem" } + + process { + Foreach($package in $ChocolateyPackage){ + $obj = @{} + $entry = [IO.Compression.Zipfile]::OpenRead($package).Entries | + Where-Object { $_.Name -match "nuspec" } + $stream = $entry.Open() + $reader = New-Object IO.StreamReader($stream) + $text = $reader.ReadToEnd() + [xml]$xml = $text + $obj.Add("Name","$($xml.package.metadata.id)") + $obj.Add("Version","$($xml.package.metadata.version)") + $reader.Close() + $stream.Close() + [pscustomobject]$obj + + } + } +} \ No newline at end of file diff --git a/functions/functions/Invoke-BoxStarterRemoteUpgrade.ps1 b/functions/functions/Invoke-BoxStarterRemoteUpgrade.ps1 new file mode 100644 index 0000000..4d4b5d1 --- /dev/null +++ b/functions/functions/Invoke-BoxStarterRemoteUpgrade.ps1 @@ -0,0 +1,52 @@ +function Invoke-BoxStarterRemoteUpgrade { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)] + [string[]]$ComputerName, + [Parameter(Mandatory=$true)] + [pscredential]$Credential, + [string[]]$AdditionalPackages, + [string[]]$ExcludedPackages, + [Parameter(Mandatory=$true)] + [string]$ScriptPath, + [switch]$Parallel + ) + + #Create dynamic upgrade list + Invoke-Command -ArgumentList $AdditionalPackages,$ExcludedPackages,$ScriptPath -ComputerName $ComputerName -ScriptBlock { + param ( + $AdditionalPackages, + $ExcludedPackages, + $ScriptPath + ) + if (Test-Path $ScriptPath) { + Remove-Item $ScriptPath -Force + } + $packages = [System.Collections.ArrayList]@(choco outdated -r --ignore-unfound --ignore-pinned | Foreach-Object { + ($_.split("|"))[0] + }) + foreach ($AddedPackage in $AdditionalPackages){ + if ($packages -notcontains $AddedPackage){ + $packages.Add($AddedPackage) | Out-Null + } + } + foreach ($ExcludedPackage in $ExcludedPackages){ + if ($packages -contains $ExcludedPackage){ + $packages.Remove($ExcludedPackage) | Out-Null + } + } + $Packages | ForEach-Object { + Add-Content $ScriptPath -Value "choco upgrade $_ -r -y --timeout=600" + } + } + #Upgrade computers with Boxstarter + if (!$Parallel){ + Install-BoxstarterPackage -ComputerName $ComputerName -PackageName $ScriptPath -DelegateChocoSources + } + else { + #Upgrade computers in parallel with Boxstarter + $ComputerName | ForEach-Object { + start-process -RedirectStandardOutput C:\Windows\Temp\$_.txt -FilePath powershell -ArgumentList "-windowstyle hidden Install-BoxstarterPackage -ComputerName $_ -PackageName $ScriptPath" -PassThru + } + } +} \ No newline at end of file diff --git a/functions/functions/Invoke-ChocoInternalizePackage.ps1 b/functions/functions/Invoke-ChocoInternalizePackage.ps1 new file mode 100644 index 0000000..c70a263 --- /dev/null +++ b/functions/functions/Invoke-ChocoInternalizePackage.ps1 @@ -0,0 +1,47 @@ +<# +.SYNOPSIS + Short description +.DESCRIPTION + Long description +.EXAMPLE + Example of how to use this cmdlet +.EXAMPLE + Another example of how to use this cmdlet +#> +function Invoke-ChocoInternalizePackage { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true,ValueFromPipeline=$True)] + [pscustomobject[]]$PackageNames, + [Parameter(Mandatory=$true)] + [string]$Path, + [switch]$PurgeWorkingDirectory + ) + begin { + if ($PurgeWorkingDirectory){ + Get-ChildItem -Path $Path -Recurse | Remove-Item -Recurse -Force + } + } + process { + Set-Location $Path + foreach ($Package in $PackageNames){ + Write-Verbose ("Downloading " + $Package.Name) + $Date = Get-Date + choco download $Package.Name --internalize --no-progress --internalize-all-urls --source chocolatey -r | Write-Verbose + $DownloadedPackages = Get-ChildItem -Path $Path | Where-Object {$_.Extension -eq '.nupkg' -AND $_.LastWriteTime -gt $Date} | Select-Object -ExpandProperty FullName + if ($LASTEXITCODE -ne 0){ + $Result = 'Internalize Failed' + } + else { + $Result = 'Internalize Success' + } + Write-Verbose ($Package.Name + ' internalize failed') + [PSCustomObject]@{ + Name = $Package.Name + Result = $Result + Version = $Package.Version + NuGetpkgs = $DownloadedPackages + } + } + } +} \ No newline at end of file diff --git a/functions/functions/Invoke-ChocoRemoteUpgrade.ps1 b/functions/functions/Invoke-ChocoRemoteUpgrade.ps1 new file mode 100644 index 0000000..b26c4f5 --- /dev/null +++ b/functions/functions/Invoke-ChocoRemoteUpgrade.ps1 @@ -0,0 +1,69 @@ +<# +.SYNOPSIS + Short description +.DESCRIPTION + Long description +.EXAMPLE + Example of how to use this cmdlet +.EXAMPLE + Another example of how to use this cmdlet +#> +function Invoke-ChocoRemoteUpgrade { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)] + [string[]]$ComputerName, + [pscredential]$Credential, + [string[]]$AdditionalPackages, + [string[]]$ExcludedPackages, + [switch]$RebootifPending + ) + process { + #Create dynamic upgrade list + Invoke-Command -ArgumentList $AdditionalPackages,$ExcludedPackages,$ScriptPath,$Credential -ComputerName $ComputerName -ScriptBlock { + param ( + $AdditionalPackages, + $ExcludedPackages, + $ScriptPath + ) + $packages = [System.Collections.ArrayList]@(choco outdated -r --ignore-unfound --ignore-pinned | Foreach-Object { + ($_.split("|"))[0] + }) + if ($AdditionalPackages){ + foreach ($AddedPackage in $AdditionalPackages){ + if ($packages -notcontains $AddedPackage){ + $packages.Add($AddedPackage) | Out-Null + } + } + } + if ($ExcludedPackages){ + foreach ($ExcludedPackage in $ExcludedPackages){ + if ($packages -contains $ExcludedPackage){ + $packages.Remove($ExcludedPackage) | Out-Null + } + } + } + foreach ($package in $packages){ + choco upgrade $package -r -y --timeout=600 | Out-File ("c:\Windows\Temp\choco-" + $package + ".txt") + if ($LASTEXITCODE -ne 0){ + $Result = 'Failed' + } + else{ + $Result = 'Success' + } + [PSCustomObject]@{ + Name = $Package + Result = $Result + Computer = $Env:COMPUTERNAME + } + } + } + #Restart machines with pending Reboot + if ($RebootifPending){ + Test-PendingReboot -ComputerName $ComputerName -SkipConfigurationManagerClientCheck | Where-Object {$_.IsRebootpending -eq $True } | ForEach-Object { + "Rebooting $($_.ComputerName)" + Restart-Computer -ComputerName $_.ComputerName -Force + } + } + } +} \ No newline at end of file diff --git a/functions/functions/Invoke-ChocoUpgradeIntPackage.ps1 b/functions/functions/Invoke-ChocoUpgradeIntPackage.ps1 new file mode 100644 index 0000000..942ca8b --- /dev/null +++ b/functions/functions/Invoke-ChocoUpgradeIntPackage.ps1 @@ -0,0 +1,39 @@ +<# +.SYNOPSIS + Short description +.DESCRIPTION + Long description +.EXAMPLE + Example of how to use this cmdlet +.EXAMPLE + Another example of how to use this cmdlet +#> +function Invoke-ChocoUpgradeIntPackage { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true,ValueFromPipeline=$True)] + [pscustomobject[]]$PackageNames, + [Parameter(Mandatory=$true)] + [string]$Path + ) + process { + foreach ($Package in $PackageNames){ + Write-Verbose ("Upgrading " + $Package.Name) + choco upgrade $Package.Name --source $Path --no-progress -y -r | Write-Verbose + #If failure detected in output continue to next package + if ($LASTEXITCODE -ne 0){ + $Result = 'Upgrade Failed' + } + else { + $Result = 'Upgrade Success' + } + Write-Verbose ($Package.Name + ' Upgrade failed') + [PSCustomObject]@{ + Name = $Package.Name + Result = $Result + Version = $Package.Version + NuGetpkgs = $Package.NuGetpkgs + } + } + } + } \ No newline at end of file diff --git a/functions/functions/Push-ChocoIntPackage.ps1 b/functions/functions/Push-ChocoIntPackage.ps1 new file mode 100644 index 0000000..02d1f11 --- /dev/null +++ b/functions/functions/Push-ChocoIntPackage.ps1 @@ -0,0 +1,45 @@ +<# +.SYNOPSIS + Short description +.DESCRIPTION + Long description +.EXAMPLE + Example of how to use this cmdlet +.EXAMPLE + Another example of how to use this cmdlet +#> +function Push-ChocoIntPackage { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true,ValueFromPipeline=$True)] + [pscustomobject[]]$PackageNames, + [Parameter(Mandatory=$true)] + [string]$Path, + [Parameter(Mandatory=$true)] + [string]$RepositoryURL, + [Parameter(Mandatory=$true)] + [ValidateNotNull()] + [System.Management.Automation.PSCredential]$ApiKey + ) + process { + foreach ($Package in $PackageNames){ + foreach ($NuPkg in $Package.NuGetpkgs) { + $MetaData = Get-ChocoPackageMetaData -ChocolateyPackage $NuPkg + choco push $NuPkg --force --source $RepositoryURL --api-key $ApiKey.GetNetworkCredential().Password --timeout=3600 | Write-Verbose + if ($LASTEXITCODE -ne 0){ + $Result = 'Push Failed' + } + else { + $Result = 'Push Success' + } + Write-Verbose "$($MetaData.Name) push failed" + [PSCustomObject]@{ + Name = $MetaData.Name + Result = $Result + Version = $MetaData.Version + NuGetPackage = $NuPkg + } + } + } + } + } \ No newline at end of file diff --git a/functions/functions/Test-ChocoUpgradeTrigger.ps1 b/functions/functions/Test-ChocoUpgradeTrigger.ps1 new file mode 100644 index 0000000..2a12088 --- /dev/null +++ b/functions/functions/Test-ChocoUpgradeTrigger.ps1 @@ -0,0 +1,37 @@ + <# + .SYNOPSIS + Short description + .DESCRIPTION + Long description + .EXAMPLE + Example of how to use this cmdlet + .EXAMPLE + Another example of how to use this cmdlet + #> + function Test-ChocoUpgradeTrigger { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true,ValueFromPipeline=$True)] + [pscustomobject[]]$PackageNames, + [Parameter(Mandatory=$true)] + [string[]]$TriggerPackages, + [Parameter(Mandatory=$true)] + [string]$UpgradeScriptPath, + [Parameter(Mandatory=$true)] + [string]$TriggeredTime, + [Parameter(Mandatory=$true)] + [System.Management.Automation.PSCredential]$Credential + ) + process { + foreach ($Package in $PackageNames){ + if ($TriggerPackages -contains $Package.Name){ + Write-Output "Creating scheduled task for $($Package.Name)" + Disable-ScheduledTask -TaskName 'Triggered Choco Upgrade' | Unregister-ScheduledTask -Confirm:$False + $Time = New-ScheduledTaskTrigger -At $TriggeredTime -Once + $PS = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument "-file $UpgradeScriptPath" + Register-ScheduledTask -User $Credential.UserName -Description 'This task is created when a certain third party software should be updated on clients' -TaskName 'Triggered Choco Upgrade' -Trigger $Time -Action $PS -Password $Credential.GetNetworkCredential().password -RunLevel Highest + Exit + } + } + } + } \ No newline at end of file