cciget.psd1

@{
RootModule        = 'cciget.psm1'
ModuleVersion     = '0.6.1'
GUID              = 'dc396cfc-ce78-467f-a87a-f24e4754ee36'
Author            = 'CCI Platform IT'
CompanyName       = 'CCI'
Copyright         = '(c) 2026 CCI. All rights reserved.'
Description       = 'Discover and install CCI internal PowerShell modules from per-tenant Azure Artifacts feeds. Uses Entra/AzDO Artifacts Credential Provider; no PATs required.'
PowerShellVersion = '5.1'

# PSResourceGet (v3) is the supported client for AzDO Artifacts NuGet v3 feeds.
# Declared as a required module so PSGallery installs it transparently for PS 5.1 users.
RequiredModules   = @(
    @{ ModuleName = 'Microsoft.PowerShell.PSResourceGet'; ModuleVersion = '1.0.0' }
)

FunctionsToExport = @(
    'Connect-CciGet'
    'Disconnect-CciGet'
    'Get-CciGetConfig'
    'Set-CciGetConfig'
    'Find-CciModule'
    'Install-CciModule'
    'Invoke-CciGetBootstrap'
    'Update-CciModule'
    'Get-CciModule'
    'Save-CciModule'
    'Publish-CciModuleToBlob'
)
CmdletsToExport   = @()
VariablesToExport = @()
AliasesToExport   = @()

PrivateData = @{
    PSData = @{
        Tags         = @('cci', 'package-management', 'azure-artifacts', 'psresourceget', 'internal-gallery')
        ProjectUri   = 'https://ccistack.ghe.com/itplatform/cciget'
        ReleaseNotes = '0.6.1 - Store installs now refresh a dependency that is present but out of date. Dependency resolution skipped anything Get-Module -ListAvailable could see, at any version, so a machine stayed pinned to whatever it happened to have: a build kept loading framework 0.2.1.12 after 0.2.1.13 shipped, and failed with the identical error that version had already been fixed for. The installed versions are now compared against the version the store index advertises. 0.6.0 - Invoke-CciGetBootstrap now installs machine-wide and requires an elevated session. A machine build hands the machine between users: the technician runs the bootstrap as a temporary local account, the sequence reboots into an autologon as the administrator account, and the second pass deletes the technician account AND its profile. Modules installed per-user sat inside that profile, so the second pass could not resolve them - a build failed after its reboot with a bare RequiredModules error - and would have deleted them mid-run had it got that far. -Scope now defaults to Auto, which means AllUsers, and refuses to continue unelevated rather than installing somewhere that cannot survive the build; pass -Scope CurrentUser explicitly to use cciget as an ordinary module installer. 0.5.0 - Invoke-CciGetBootstrap prepares a freshly built machine in one command: it connects, installs the module the tenant nominates (registry: bootstrapModule), imports it into the caller session, and runs whatever entry point that module declares (manifest: PrivateData.CciGet.BootstrapCommand). cciget learns nothing tenant-specific, because both ends are declarations. Missing values are resolved from the argument completer the target command already publishes, so a single candidate is taken silently and several are offered as a numbered choice. -SkipFinalStep (alias -SkipPublish) installs without running the entry point. An established connection is now reused rather than re-resolved, which previously could move a session pointed at the store onto the feed. 0.4.1 - Module-name completion offers the short name a user types (wincustpayload) rather than the tenant-prefixed one; 0.4.0 sorted the candidates alphabetically, which put the prefixed name first. 0.4.0 - Guided flow. Connect-CciGet now lists the modules the tenant actually offers and names the next command; Install-CciModule says what to import afterwards, and surfaces a module-declared next step from its manifest (PrivateData.CciGet.NextStep). Module names and tenants tab-complete on Install/Save/Update/Find-CciModule. Installing a module does not load it, so a build that stopped after installing hit a confusing "nothing is registered" error on the next command with no indication of the missing step. 0.3.2 - Fixes installing from the distribution store on Windows PowerShell 5.1, which is what machine builds run. The container listing comes back as UTF-8 with a BOM but no charset in the Content-Type, so 5.1 decodes it as ISO-8859-1 and the cast to XML fails; the body is now decoded from raw bytes as UTF-8. PowerShell 7 decodes correctly, so this passed every workstation test and failed only on the machine it exists for. Module sources are now ASCII-only and tests run on both hosts. 0.3.1 - Device-code sign-in read the token endpoint error body only the way Windows PowerShell 5.1 exposes it, so on PowerShell 7 the routine authorization_pending response could not be parsed and the sign-in aborted the moment polling began. Both shapes are now handled. 0.3.0 - The distribution store no longer uses Az PowerShell. Az.Accounts device-code sign-in is broken on the Windows PowerShell 5.1 that freshly built machines run ("the type initializer for MsalJsonSerializerContext threw an exception"), and pulling Az.Accounts + Az.Storage during OOBE costs hundreds of MB. Sign-in and blob access are now plain REST against the Entra device-code endpoint and the Blob service, so cciget has no Azure dependency beyond HTTPS. Also: blob request failures now throw instead of being written to the error stream, which previously let a partially downloaded module report success; failed installs remove the partial folder; and the module initialises its script state so the store path does not trip Set-StrictMode. 0.2.1 - ONE sign-in. Connect-CciGet now selects its source before prompting: a live Azure CLI session uses the feed (no prompt), otherwise the tenant distribution store (one device code, no Azure DevOps entitlement and no credential-provider download), falling back to the feed only if the store is unavailable. 0.2.0 always tried the feed first, so a machine builder completed TWO device codes - one of them for a resource they cannot use. Adds -Source Auto|Feed|Store. 0.2.0 - Tenant distribution store: modules can now be served from the tenant Azure storage account (Entra/Azure-RBAC gated) as well as the Azure Artifacts feed. Reading an Artifacts feed requires an Azure DevOps org entitlement plus a paid Basic licence per user (Stakeholder has no Artifacts access), which machine builders neither have nor need - they already hold Azure RBAC on the tenant store for customization payloads. Install-CciModule resolves RequiredModules recursively from it; Publish-CciModuleToBlob mirrors a built module into it. 0.1.2 - Fixes three fresh-machine sign-in faults found on a real build: device-code sign-in now allows 10 minutes instead of the provider default 90s; the credential provider is forced to device-code flow instead of the WAM broker dialog, which fails with 0x800703f0 on freshly built machines; and a malformed hint string that made Connect-CciGet fail with PositionalParameterNotFound on its own error path. 0.1.1 - Connect-CciGet drives the Azure Artifacts Credential Provider directly when no Azure CLI session is present, instead of relying on the provider being able to prompt from PSResourceGet plugin mode. 0.1.0 - Initial preview.'
    }
}
}