{"id":16480873,"url":"https://github.com/pauby/capu","last_synced_at":"2025-06-17T03:07:29.567Z","repository":{"id":73243308,"uuid":"134899294","full_name":"pauby/capu","owner":"pauby","description":"Chocolatey Automatic Package Updater","archived":false,"fork":false,"pushed_at":"2023-06-05T10:45:17.000Z","size":803,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-16T11:59:30.050Z","etag":null,"topics":["chocolatey","chocolatey-automatic","powershell","powershell-module"],"latest_commit_sha":null,"homepage":null,"language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pauby.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-25T19:57:30.000Z","updated_at":"2024-08-30T05:56:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"04171af0-ba2a-4daa-a503-4db54c52de64","html_url":"https://github.com/pauby/capu","commit_stats":{"total_commits":539,"total_committers":9,"mean_commits":"59.888888888888886","dds":"0.10946196660482377","last_synced_commit":"6c908e6ac12fc74463d8a310d22c65c7a30b420c"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/pauby/capu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pauby%2Fcapu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pauby%2Fcapu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pauby%2Fcapu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pauby%2Fcapu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pauby","download_url":"https://codeload.github.com/pauby/capu/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pauby%2Fcapu/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260281567,"owners_count":22985629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chocolatey","chocolatey-automatic","powershell","powershell-module"],"created_at":"2024-10-11T13:05:38.213Z","updated_at":"2025-06-17T03:07:29.551Z","avatar_url":"https://github.com/pauby.png","language":"PowerShell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CAPU\r\n\r\nThis PowerShell module is a fork of the MIT Licensed version of [AU](https://github.com/majkinetor/au). The purpose of the fork is:\r\n\r\n* Refactor the code to follow PowerShell best practices and standards (where there are any);\r\n* Make the code easier to understand;\r\n* Make the module easier to use;\r\n\r\nPrimarily the fork is really for me but other may get some use of it.\r\n\r\nThe rest of this README contains documentation and links to the original AU repository and these will be replaced over time.\r\n\r\n# Chocolatey Automatic Package Updater Module\r\n\r\nThis PowerShell module implements functions that can be used to automate [Chocolatey](https://chocolatey.org) package updates.\r\n\r\nTo learn more about Chocolatey automatic packages, please refer to the relevant [documentation](https://github.com/chocolatey/choco/wiki/AutomaticPackages).  \r\nTo see AU in action see [video tutorial](https://www.youtube.com/watch?v=m2XpV2LxyEI\u0026feature=youtu.be).\r\n\r\n## Features\r\n\r\n- Use only PowerShell to create automatic update script for given package.\r\n- Automatically downloads installers and provides/verifies checksums for x32 and x64 versions.\r\n- Verifies URLs, nuspec versions, remote repository existence etc.\r\n- Can use global variables to change functionality.\r\n- Sugar functions for Chocolatey package maintainers.\r\n- Update single package or any subset of previously created AU packages with a single command.\r\n- Multithread support when updating multiple packages.\r\n- Plugin system when updating everything, with few integrated plugins to send email notifications, save results to gist and push updated packages to git repository.\r\n\r\n\r\n## Installation\r\n\r\nAU module requires minimally PowerShell version 5: `$host.Version -ge '5.0'`\r\n\r\nTo install it, use one of the following methods:\r\n- PowerShell Gallery: [`Install-Module au`](https://www.powershellgallery.com/packages/AU).  \r\n- Chocolatey:  [`choco install au`](https://chocolatey.org/packages/au). \r\n- [Download](https://github.com/majkinetor/au/releases/latest) latest 7z package or latest build [artifact](https://ci.appveyor.com/project/majkinetor/au/build/artifacts).\r\n\r\n\r\nTo quickly start using AU, fork [au-packages-template](https://github.com/majkinetor/au-packages-template) repository and rename it to `au-packages`.\r\n\r\n**NOTE**: All module functions work from within specific root folder. The folder contains all of your Chocolatey packages.\r\n\r\n## Creating the package updater script\r\n\r\nThe AU uses `update.ps1` script that package maintainers should create in the package directory. No templates are used, just plain PowerShell.\r\n\r\nTo write the package update script, it is generally required to implement 2 functions: `au_GetLatest` and `au_SearchReplace`.\r\n\r\n### `au_GetLatest`  \r\n\r\nThis function is used to get the latest package information.\r\n\r\nAs an example, the following function uses [Invoke-WebRequest](https://technet.microsoft.com/en-us/library/hh849901.aspx?f=255\u0026MSPPError=-2147217396) to download a page (#1). After that it takes a `href` attribute from the first page link that ends with `.exe` word as a latest URL for the package (#2). Then it conveniently splits the URL to get the latest version for the package (#3), a step that is highly specific to the URL but very easy to determine.\r\n\r\n```powershell\r\nfunction global:au_GetLatest {\r\n     $download_page = Invoke-WebRequest -Uri $releases #1 \r\n     $regex   = '.exe$'\r\n     $url     = $download_page.links | ? href -match $regex | select -First 1 -expand href #2\r\n     $version = $url -split '-|.exe' | select -Last 1 -Skip 2 #3\r\n     return @{ Version = $version; URL32 = $url }\r\n}\r\n```\r\n\r\nThe returned version is later compared to the one in the nuspec file and if remote version is higher, the files will be updated. The returned keys of this HashTable are available via global variable `$global:Latest` (along with some keys that AU generates). You can put whatever data you need in the returned HashTable - this data can be used later in `au_SearchReplace`.\r\n\r\n\r\n### `au_SearchReplace`  \r\n\r\nFunction returns HashTable containing search and replace data for any package file in the form:  \r\n\r\n```powershell\r\n    @{\r\n        file_path1 = @{\r\n            search1 = replace1\r\n            ...\r\n            searchN = replaceN\r\n        }\r\n        file_path2 = @{ ... }\r\n        ...\r\n    }\r\n```\r\n\r\nSearch and replace strings are operands for PowerShell [replace](http://www.regular-expressions.info/powershell.html) operator. You do not have to write them most of the time however, they are rarely changed.\r\n\r\nFile paths are relative to the package directory. The function can use `$global:Latest` variable to get any type of information obtained when `au_GetLatest` was executed along with some AU generated data such as `PackageName`, `NuspecVersion` etc. \r\n\r\nThe following example illustrates the usage:\r\n\r\n```powershell\r\nfunction global:au_SearchReplace {\r\n    @{\r\n        \"tools\\chocolateyInstall.ps1\" = @{\r\n            \"(^[$]url32\\s*=\\s*)('.*')\"      = \"`$1'$($Latest.URL32)'\"           #1\r\n            \"(^[$]checksum32\\s*=\\s*)('.*')\" = \"`$1'$($Latest.Checksum32)'\"      #2\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nHere, line of the format `$url32 = '\u003cpackage_url\u003e'` in the file `tools\\chocolateyInstall.ps1` will have its quoted string replaced with latest URL (#1). The next line replaces value of the variable `$checksum32` on the start of the line with the latest checksum that is automatically injected in the `$Latest` variable by the AU framework (#2). Replacement of the latest version in the nuspec file is handled automatically. \r\n\r\n**NOTE**: The search and replace works on lines, multiple lines can not be matched with single regular expression.\r\n\r\n### Update \r\n\r\nWith above functions implemented calling the `Update-Package` (alias `update`) function from the AU module will update the package when needed.\r\n\r\nYou can then update the individual package by running the appropriate `update.ps1` script from within the package directory:\r\n\r\n```\r\nPS C:\\chocolatey\\dngrep\u003e .\\update.ps1\r\ndngrep - checking updates using au version 2016.9.14\r\nnuspec version: 2.8.15.0\r\nremote version: 2.8.16.0\r\nNew version found\r\nAutomatic checksum started\r\nDownloading dngrep 32 bit\r\n  from 'https://github.com/dnGrep/dnGrep/releases/download/v2.8.16.0/dnGREP.2.8.16.x86.msi'\r\n\r\nDownload of dnGREP.2.8.16.x86.msi (3.36 MB) completed.\r\nPackage downloaded and hash calculated for 32 bit version\r\nDownloading dngrep 64 bit\r\n  from 'https://github.com/dnGrep/dnGrep/releases/download/v2.8.16.0/dnGREP.2.8.16.x64.msi'\r\n\r\nDownload of dnGREP.2.8.16.x64.msi (3.39 MB) completed.\r\nPackage downloaded and hash calculated for 64 bit version\r\nUpdating files\r\n  dngrep.nuspec\r\n    updating version:  2.8.15.0 -\u003e 2.8.16.0\r\n  tools\\chocolateyInstall.ps1\r\n    (^[$]url32\\s*=\\s*)('.*') = $1'https://github.com/dnGrep/dnGrep/releases/download/v2.8.16.0/dnGREP.2.8.16.x86.msi'\r\n    (^[$]url64\\s*=\\s*)('.*') = $1'https://github.com/dnGrep/dnGrep/releases/download/v2.8.16.0/dnGREP.2.8.16.x64.msi'\r\n    (^[$]checksum32\\s*=\\s*)('.*') = $1'CE4753735148E1F48FE0E1CD9AA4DFD019082F4F43C38C4FF4157F08D346700C'\r\n    (^[$]checksumType32\\s*=\\s*)('.*') = $1'sha256'\r\n    (^[$]checksum64\\s*=\\s*)('.*') = $1'025BD4101826932E954AACD3FE6AEE9927A7198FEEFFB24F82FBE5D578502D18'\r\n    (^[$]checksumType64\\s*=\\s*)('.*') = $1'sha256'\r\nAttempting to build package from 'dngrep.nuspec'.\r\nSuccessfully created package 'dngrep.2.8.16.0.nupkg'\r\nPackage updated\r\n```\r\n\r\nThis is best understood via the example - take a look at the real life package [installer script](https://github.com/majkinetor/au-packages/blob/master/dngrep/tools/chocolateyInstall.ps1) and its [AU updater](https://github.com/majkinetor/au-packages/blob/master/dngrep/update.ps1).\r\n\r\n### Checks\r\n\r\nThe `update` function does the following checks:\r\n\r\n- The `$Latest.Version` will be checked to match a valid nuspec pattern.\r\n- Any hash key that starts with the word `Url`, will be checked for existence and MIME textual type, since binary is expected here.\r\n- If the remote version is higher then the nuspec version, the Chocolatey site will be checked for existence of this package version (this works for unpublished packages too). This allows multiple users to update same set of packages without a conflict. Besides, this feature makes it possible not to persist state between the updates as once the package is updated and pushed, the next update will not push the package again. To persist the state of updated packages you can use for instance [Git](https://github.com/majkinetor/au/blob/master/AU/Plugins/Git.ps1) plugin which saves the updated and published packages to the git repository. \r\n- The regex patterns in `au_SearchReplace` will be checked for existence.\r\n\r\nIf any of the checks fails, package will not get updated. This feature releases you from the worries about how precise is your pattern match in both `au_` functions - if for example, a vendor site changes, the package update will fail because of the wrongly parsed data. \r\n\r\nFor some packages, you may want to disable some of the checks by specifying additional parameters of the `update` function (not all can be disabled):\r\n\r\n| Parameter             | Description                       |\r\n| ---------             | ------------                      |\r\n| `NoCheckUrl`          | Disable URL checks                |\r\n| `NoCheckChocoVersion` | Disable the Chocolatey site check |\r\n| `ChecksumFor none`    | Disable automatic checksum        |\r\n\r\n### Automatic checksums\r\n\r\nWhen new version is available, the `update` function will by default download both x32 and x64 versions of the installer and calculate the desired checksum. It will inject this info in the `$global:Latest` HashTable variable so you can use it via `au_SearchReplace` function to update hashes. The parameter `ChecksumFor` can contain words `all`, `none`, `32` or `64` to further control the behavior.\r\n\r\nYou can disable this feature by calling update like this:\r\n\r\n    update -ChecksumFor none\r\n\r\nYou can define the hash algorithm by returning corresponding `ChecksumTypeXX` hash keys in the `au_GetLatest` function:\r\n\r\n    return @{ ... ChecksumType32 = 'sha512'; ... }\r\n\r\nIf the checksum is actually obtained from the vendor's site, you can provide it along with its type (SHA256 by default) by returning corresponding `ChecksumXX` hash keys in the `au_GetLatest` function:\r\n\r\n    return @{ ... Checksum32 = 'xxxxxxxx'; ChecksumType32 = 'md5'; ... }\r\n\r\nIf the `ChecksumXX` hash key is present, the AU will change to checksum verification mode - it will download the installer and verify that its checksum matches the one provided. If the key is not present, the AU will calculate hash with the given `ChecksumTypeXX` algorithm.\r\n\r\n**NOTE**: This feature works by monkey patching the `Get-ChocolateyWebFile` helper function and invoking the `chocolateyInstall.ps1` afterwards for the package in question. This means that it downloads the files using whatever method is specified in the package installation script.\r\n\r\n\r\n### Manual checksums\r\n\r\nSometimes invoking `chocolateyInstall.ps1` during the automatic checksum could be problematic so you need to disable it using update option `ChecksumFor none` and get the checksum some other way. Function `Get-RemoteChecksum` can be used to simplify that:\r\n\r\n```powershell\r\n  function au_BeforeUpdate() {\r\n     $Latest.Checksum32 = Get-RemoteChecksum $Latest.Url32\r\n  }\r\n\r\n  function au_GetLatest() {\r\n    download_page = Invoke-WebRequest $releases -UseBasicParsing\r\n    $url     = $download_page.links | ? href -match '\\.exe$' | select -First 1 -expand href\r\n    $version = $url -split '/' | select -Last 1 -Skip 1\r\n    @{\r\n        URL32     = $url\r\n        Version   = $version\r\n    }\r\n  }\r\n```\r\n\r\n### Force update\r\n\r\nYou can force the update even if no new version is found by using the parameter `Force` (or global variable `$au_Force`). This can be useful for testing the update and bug fixing, recalculating the checksum after the package was created and already pushed to Chocolatey or if URLs to installer changed without change in version.\r\n\r\n**Example**:\r\n\r\n```\r\nPS C:\\chocolatey\\cpu-z.install\u003e $au_Force = $true; .\\update.ps1\r\ncpu-z.install - checking updates\r\nnuspec version: 1.77\r\nremote version: 1.77\r\nNo new version found, but update is forced\r\nAutomatic checksum started\r\n...\r\nUpdating files\r\n  cpu-z.install.nuspec\r\n    updating version using Chocolatey fix notation: 1.77 -\u003e 1.77.0.20160814\r\n...\r\n```\r\n\r\nForce option changes how package version is used. Without force, the `NuspecVersion` determines what is going on. Normally, if `NuspecVersion` is lower or equal then the `RemoteVersion` update happens. With `Force` this changes:\r\n\r\n1. If `NuspecVersion` is lower then `RemoteVersion`, Force is ignored and update happens as it would normally\r\n2. If `NuspecVersion` is the same as the `RemoteVersion`, the version will change to chocolatey fix notation.\r\n3. If the `NuspecVersion` is already using chocolatey fix notation, the version will be updated to fix notation for the current date.\r\n4. If the `NuspecVersion` is higher then the `RemoteVersion` update will happen but `RemoteVersion` will be used.\r\n\r\nPoints 2-4 do not apply if you set the explicit version using the variable `au_Version`.\r\n\r\n[Chocolatey fix notation](https://github.com/chocolatey/choco/wiki/CreatePackages#package-fix-version-notation) changes a version so that current date is added in the _revision_ component of the package version in the format `yyyyMMdd`. More precisely: \r\n\r\n- chocolatey _fix version_ always ends up in to the _Revision_ part of the package version;\r\n- existing _fix versions_ are changed to contain the current date;\r\n- if _revision_ part is present in the package version and it is not in the _chocolatey fix notation_ form, AU will keep the existing version but notify about it;\r\n\r\nForce can be triggered also from the `au_GetLatest` function. This may be needed if remote version doesn't change but there was nevertheless change on the vendor site. See the [example](https://github.com/majkinetor/au-packages/blob/master/cpu-z.install/update.ps1#L18-L39) on how to update the package when remote version is unchanged but hashsum of the installer changes.\r\n\r\n### Global variables\r\n\r\nTo avoid changing the `./update.ps1` when troubleshooting or experimenting you can set up any **already unset** `update` parameter via global variable. The names of global variables are the same as the names of parameters with the prefix `au_`. As an example, the following code will change the update behavior so that URL is not checked for existence and MIME type and update is forced: \r\n\r\n    $au_NoCheckUrl = $au_Force = $true\r\n    ./update.ps1\r\n\r\nThis is the same as if you added the parameters to `update` function inside the `./update.ps1` script:\r\n\r\n    update -NoCheckUrl -Force\r\n\r\nhowever, its way easier to setup global variable with manual intervention on multiple packages.\r\n\r\n### Reusing the AU updater with metapackages\r\n\r\nMetapackages can reuse an AU updater of its dependency by the following way:\r\n\r\n- In the dependent updater, instead of calling the `update` directly, use construct:\r\n\r\n  ```\r\n    if ($MyInvocation.InvocationName -ne '.') { update ... }\r\n  ```\r\n\r\n- In the metapackage updater dot source the dependent updater and override `au_SearchReplace`.\r\n\r\nThis is best understood via example - take a look at the [cpu-z](https://github.com/majkinetor/au-packages/blob/master/cpu-z/update.ps1) AU updater which uses the updater from the [cpu-z.install](https://github.com/majkinetor/au-packages/blob/master/cpu-z.install/update.ps1) package on which it depends. It overrides the `au_SearchReplace` function and the `update` call but keeps the `au_GetLatest`.\r\n\r\n\r\n### Embedding binaries\r\n\r\n**NOTE**: Unpublished, only on master branch.\r\n\r\nEmbedded packages do not download software from the Internet but contain binaries inside the package. This makes package way more stable as it doesn't depend on the network for installation. AU function `Get-RemoteFiles` can download files and save them in the package's `tools` directory. It does that by using the `$Latest.URL32` and/or `$Latest.URL64`. \r\n\r\nThe following example downloads files inside `au_BeforeUpdate` function which is called before the package files are updated with the latest data (function is not called if no update is available): \r\n\r\n```powershell\r\nfunction au_BeforeUpdate() {\r\n    #Download $Latest.URL32 / $Latest.URL64 in tools directory and remove any older installers.\r\n    Get-RemoteFiles -Purge\r\n}\r\n```\r\n\r\nThis function will also set the appropriate `$Latest.ChecksumXX`.\r\n\r\n## Updating all packages\r\n\r\nYou can update all packages and optionally push them to the Chocolatey repository with a single command. Function `Update-AUPackages` (alias `updateall`) will iterate over `update.ps1` scripts and execute each in a separate thread. If it detects that a package is updated it will optionally try to push it to the Chocolatey repository and may also run configured plugins.\r\n\r\nFor the push to work, specify your Choocolatey API key in the file `api_key` in the script's directory (or its parent directory) or set the environment variable `$Env:api_key`. If none provided cached nuget key will be used.\r\n\r\nThe function will search for packages in the current directory. To override that, use global variable `$au_Root`:\r\n\r\n    PS\u003e $au_root = 'c:\\chocolatey_packages`\r\n    PS\u003e $Options = @{\r\n        Timeout = 10\r\n        Threads = 15\r\n        Push    = $true\r\n    }\r\n    PS\u003e updateall -Options $Options\r\n\r\n    Updating 6 automatic packages at 2016-09-16 22:03:33\r\n    Push is enabled\r\n       copyq is updated to 2.6.1 and pushed \r\n       dngrep had errors during update\r\n           Can't validate URL 'https://github.com/dnGrep/dnGrep/releases/download/v2.8.16.0/dnGREP.2.8.16.x64.msi'\r\n           Exception calling \"GetResponse\" with \"0\" argument(s): \"The operation has timed out\"\r\n       eac has no updates\r\n       pandoc has no updates\r\n       plantuml has no updates\r\n       yed had errors during update\r\n           Can't validate URL 'https://www.yworks.com'\r\n           Invalid content type: text/html\r\n\r\n    Finished 6 packages after .32 minutes.\r\n    1 updated and 1 pushed.\r\n    2 errors - 2 update, 0 push.\r\n\r\n\r\nUse `updateall` parameter `Name` to specify package names via glob, for instance `updateall [a-d]*` would update only packages which names start with the letter 'a' trough 'd'. Add `Push` among options to push successfully built packages to the chocolatey repository.\r\n\r\nTake a look at the [real life example](http://tiny.cc/v1u1ey) of the update script. To see all available options for `updateall` type `man updateall -Parameter Options`.\r\n\r\n### Plugins\r\n\r\nIt is possible to specify a custom user logic in `Options` parameter - every key that is of type `[HashTable]` will be considered plugin with the PowerShell script that is named the same as the key. The following code shows how to use 5 integrated plugins:\r\n\r\n```powershell\r\n    $Options = [ordered]@{\r\n        Timeout = 100\r\n        Threads = 15\r\n        Push    = $true\r\n          \r\n        # Save text report in the local file report.txt\r\n        Report = @{\r\n            Type = 'text'\r\n            Path = \"$PSScriptRoot\\report.txt\"\r\n        }\r\n        \r\n        # Then save this report as a gist using your api key and gist id\r\n        Gist = @{\r\n            ApiKey = $Env:github_api_key\r\n            Id     = $Env:github_gist_id\r\n            Path   = \"$PSScriptRoot\\report.txt\"\r\n        }\r\n\r\n        # Persist pushed packages to your repository\r\n        Git = @{\r\n            User = ''\r\n            Password = $Env:github_api_key\r\n        }\r\n        \r\n        # Then save run info which can be loaded with Import-CliXML and inspected\r\n        RunInfo = @{\r\n            Path = \"$PSScriptRoot\\update_info.xml\"\r\n        }\r\n\r\n        # Finally, send an email to the user if any error occurs and attach previously created run info\r\n        Mail = if ($Env:mail_user) {\r\n                @{\r\n                   To          = $Env:mail_user\r\n                   Server      = 'smtp.gmail.com'\r\n                   UserName    = $Env:mail_user\r\n                   Password    = $Env:mail_pass\r\n                   Port        = 587\r\n                   EnableSsl   = $true\r\n                   Attachment  = \"$PSScriptRoot\\$update_info.xml\"\r\n                   UserMessage = 'Save attachment and load it for detailed inspection: \u003ccode\u003e$info = Import-CliXCML update_info.xml\u003c/code\u003e'\r\n                }\r\n        } else {}\r\n    }\r\n```\r\n\r\nThe plugins above - `Report`, `Gist`,`Git`,`RunInfo` and `Mail` -  are executed in the given order (hence the `[ordered]` flag) and AU passes them given options and saves the run results. \r\n\r\nTo add custom plugins, specify additional plugin search path via `$Options.PluginPath`. Plugin is a normal PowerShell script and apart from parameters given in its HashTable the AU will send it one more parameter `$Info` that contains current run info. The name of the script file must be the same as that of the key which value is used to pass the parameters to the plugin. If a key with the value of type `[HashTable]` doesn't point to existing PowerShell script it is not considered to be an AU plugin.\r\n\r\nTo temporary disable plugins use `updateall` option `NoPlugins` or global variable `$au_NoPlugins`.\r\nTo temporary exclude the AU package from `updateall` procedure add `_` prefix to the package directory name.\r\n\r\nYou can also execute a custom script via ScriptBlock specified via `BeforeEach` and `AfterEach` options. They will receive 2 parameters - package name and Options HashTable which you can use to pass any other parameter.\r\n\r\nFor more information take a look at the wiki section about [plugins](https://github.com/majkinetor/au/wiki/Plugins).\r\n\r\n### Make a script\r\n\r\nIts desirable to put everything in a single script `update_all.ps1` so it can be scheduled and called with the given options. Rename `update_all_default.ps1` and uncomment and set the options you need. \r\n\r\nTo make a local scheduled task, use the following code in the directory where your `update_all.ps1` script is found to install it:\r\n\r\n    $At = '03:00'\r\n    schtasks /create /tn \"Update-AUPackages\" /tr \"powershell -File '$pwd\\update_all.ps1'\" /sc daily /st $At\r\n\r\nIts preferable to run the updater on [AppVeyor](https://github.com/majkinetor/au/wiki/AppVeyor).\r\n\r\n### Ignoring specific errors\r\n\r\nWhen errors occur during the update, email will be sent to the owner and report will contain [errors](https://gist.github.com/gep13/bd2eaa76f2a9ab739ca0544c502dca6e/c71d4eb3f6de2848f41c1b92e221737d775f0b6f#errors) section. Some network errors are expectable and you may want to ignore them - package that failed will get updated in one of the subsequent runs anyway. To ignore an error, use try/catch block around update and return 'ignore' word from the `./update.ps1` script:\r\n\r\n    try {\r\n        update\r\n    } catch {\r\n        $ignore = 'Unable to connect to the remote server'\r\n        if ($_ -match $ignore) { Write-Host $ignore; 'ignore' }  else { throw $_ }\r\n    }\r\n    \r\n\r\nThe package will get shown in the report as [ignored](https://gist.github.com/gep13/bd2eaa76f2a9ab739ca0544c502dca6e/db5313020d882945d8fcc3a10f5176263bb837a6#quicktime) and no errors will be shown.\r\n\r\n## Other functions\r\n\r\nApart from the functions used in the updating process, there are few suggars for regular maintenance of the package:\r\n\r\n- Test-Package  \r\nQuickly test install and/or uninstall of the package from the current directory with optional parameters. This function can be used to start testing in [chocolatey-test-environment](https://github.com/majkinetor/chocolatey-test-environment) via `Vagrant` parameter.\r\n\r\n- Push-Package  \r\nPush the latest package using your API key.\r\n\r\n- Get-AuPackages (alias `gau` or `lsau`)  \r\nReturns the list of the packages which have `update.ps1` script in its directory and which name doesn't start with '_'.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpauby%2Fcapu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpauby%2Fcapu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpauby%2Fcapu/lists"}