Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
7e27040
Update Get-CCSADComputerNames.ps1
Mark5900 Apr 24, 2025
9137cce
Update test values and set default for DomainOUPath
Mark5900 Nov 19, 2025
13f0642
Refactor logging to use $Global:Cs.Job_WriteLog
Mark5900 Nov 19, 2025
3f34e93
Add comprehensive tests and refactor Add-CCSADComputerToSecurityGroup
Mark5900 Dec 5, 2025
ebecd93
Load all Dev scripts in test setup
Mark5900 Dec 5, 2025
20e0a7b
Add structured error handling for CCS operations
Mark5900 Dec 5, 2025
344d735
Improve error handling and test coverage for Add-CCSADComputerToSecur…
Mark5900 Dec 5, 2025
44a3f7e
Update Invoke-CCSErrorHandling.Tests.ps1
Mark5900 Dec 16, 2025
13d5f36
Update Add-CCSADComputerToSecurityGroup.Tests.ps1
Mark5900 Dec 16, 2025
f527baf
Update Remove-CCSADComputer.Tests.ps1
Mark5900 Dec 16, 2025
34ec2a8
fix: #436 and enhance Add-CCSADUserToSecurityGroup
Mark5900 Dec 16, 2025
e116270
Update unittests
Mark5900 Dec 17, 2025
ad6ba2e
feat: Add cleanup of temp folder in New-CapaPowerPack
Mark5900 Dec 17, 2025
fb9cac8
Update unittests
Mark5900 Dec 17, 2025
5aa7af7
fix: Delete all logs in Start-ScriptLogging
Mark5900 Dec 17, 2025
4246b3c
Update unittest
Mark5900 Dec 17, 2025
c364c2d
Update UnitTests.yml
Mark5900 Dec 17, 2025
86c9d37
Update unittests
Mark5900 Dec 17, 2025
c9be552
Update Initialize-PpInputObject.Tests.ps1
Mark5900 Dec 17, 2025
89e0e2f
fix: #432 Add-CCSADDomainLocalSecurityGroup tests and enhanced
Mark5900 Dec 17, 2025
297b60e
fix: #434 Add-CCSADGlobalSecurityGroup tests and enhanced
Mark5900 Dec 17, 2025
5f0c731
fix: #435 Add-CCSADUniversalSecurityGroup tests and enhanced
Mark5900 Dec 17, 2025
047ab45
Fix typo in dependencies README
Mark5900 Dec 18, 2025
f823dad
Add tests and enhance Get-CCSADComputerNames function
Mark5900 Dec 18, 2025
bd94176
Refactor Get-CCSEncryptedPassword and improve tests
Mark5900 Dec 18, 2025
2c9a863
Refactor Initialize-CCS and expand Pester test coverage
Mark5900 Dec 18, 2025
d76bf2a
Enhance Remove-CCSADComputer with validation and pipeline support
Mark5900 Dec 18, 2025
a89d9f3
Update UnitTests.yml
Mark5900 Dec 18, 2025
692748b
feat: Add Create-CCSADSecurityGroupsForShares cmdlet
Mark5900 Dec 18, 2025
03d6ab1
Update Create-CCSADSecurityGroupsForShares.Tests.ps1
Mark5900 Dec 18, 2025
1b18ff5
Update Create-CCSADSecurityGroupsForShares.Tests.ps1
Mark5900 Dec 18, 2025
52ab51b
Exclude Integration and Performance tests from CI
Mark5900 Dec 18, 2025
4e0faf8
feat: Add Get-CCSADComputerOU function
Mark5900 Dec 18, 2025
eab0f48
feat: Add Get-CCSADCustomAttributeForUser cmdlet
Mark5900 Dec 18, 2025
6073460
feat: Add Get-CCSADDescriptionForGroup cmdlet
Mark5900 Dec 18, 2025
0ef214a
feat: Add Get-CCSADDisplayNameForUser function
Mark5900 Dec 18, 2025
30e0d2a
feat: Add Get-CCSADEmailForUser function
Mark5900 Dec 18, 2025
6cecb69
feat: Add Get-CCSADLastLoginForComputers cmdlet
Mark5900 Dec 18, 2025
e6b64c6
feat: Add Get-CCSADOUStructure cmdlet
Mark5900 Dec 18, 2025
f9e2e7b
feat: Add Get-CCSADSid function
Mark5900 Dec 18, 2025
341029e
feat: Add Confirm-CCSADUser function
Mark5900 Dec 19, 2025
d937647
Update Initialize-CCS.ps1
Mark5900 Dec 19, 2025
3b802c0
feat: Add Move-CCSADComputer function
Mark5900 Dec 19, 2025
4cba29a
feat: Add Remove-CCSADComputerFromSecurityGroup cmdlet
Mark5900 Dec 19, 2025
b6e3b57
feat: Add Remove-CCSADUserFromSecurityGroup cmdlet
Mark5900 Dec 19, 2025
c7a25ae
feat: Add Test-CCSADIsUserMemberOfGroup cmdlet
Mark5900 Dec 19, 2025
3a6dc3f
Update Initialize-CCS.Tests.ps1
Mark5900 Dec 19, 2025
a508384
Update New-CapaPowerPack.Tests.ps1
Mark5900 Dec 19, 2025
79e34c4
Update New-CapaPowerPack.Tests.ps1
Mark5900 Jan 5, 2026
bcf8e42
Update New-CapaPowerPack.Tests.ps1
Mark5900 Jan 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions .github/workflows/UnitTests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
- dev
- CI_6.7
- Add-CCS
paths:
- "Modules/**"
workflow_dispatch:
Expand All @@ -23,16 +23,48 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Create Credential File
env:
DOMAINADMINUSERNAME: ${{ secrets.DOMAINADMINUSERNAME }}
DOMAINADMINPASSWORD: ${{ secrets.DOMAINADMINPASSWORD }}
run: |
$Path = "D:\PowerShell\Credentials\$($env:USERNAME)DomainAdminPesterTests.xml"

if (Test-Path $Path) {
Remove-Item $Path -Force
}

$securePassword = ConvertTo-SecureString $env:DOMAINADMINPASSWORD -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($env:DOMAINADMINUSERNAME, $securePassword)
$credential | Export-Clixml -Path $Path
shell: pwsh

- name: Run Pester
run: |
Import-Module Pester
$configuration = New-PesterConfiguration
$configuration.Run.Exit = $true
$configuration.TestResult.OutputPath = 'C:\Temp\PesterTests.xml'
$configuration.TestResult.Enabled = $true
$configuration.TestResult.OutputFormat = 'JUnitXml'

Invoke-Pester -Configuration $configuration
$LogFolder = 'C:\Temp'
$LogFileName = 'PesterTests.log'

if (-Not (Test-Path $LogFolder)) {
New-Item -Path $LogFolder -ItemType Directory | Out-Null
}

if (Test-Path "$LogFolder\$LogFileName") {
Remove-Item "$LogFolder\$LogFileName" -Force
}

Start-Transcript -Path "$LogFolder\$LogFileName" -Append

Import-Module Pester
$configuration = New-PesterConfiguration
$configuration.Run.Exit = $true
$configuration.TestResult.OutputPath = 'C:\Temp\PesterTests.xml'
$configuration.TestResult.Enabled = $true
$configuration.TestResult.OutputFormat = 'JUnitXml'
$configuration.Output.Verbosity = 'Detailed'
$configuration.Filter.ExcludeTag = @('Integration', 'Performance')

Invoke-Pester -Configuration $configuration
Stop-Transcript
shell: pwsh

- name: Upload Test Report
Expand All @@ -42,6 +74,13 @@ jobs:
name: Pester Test Report
path: 'C:\Temp\PesterTests.xml'

- name: Upload Test Log
if: always()
uses: actions/upload-artifact@v4
with:
name: Pester Test Log
path: 'C:\Temp\PesterTests.log'

- name: Test Report
if: always()
uses: dorny/test-reporter@v2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,232 @@
# TODO: #431 Write tests for Add-CCSADComputerToSecurityGroup
$Url = 'https://mracapa02.capainstaller.com/CCSWebservice/CCS.asmx'
$CCSCredential = Get-Credential
$DomainCredential = Get-Credential
Add-CCSADComputerToSecurityGroup -ComputerName 'MRADTEST02' -SecurityGroupName 'TestGruppe' -Domain 'Firmax.local' -Url $Url -CCSCredential $CCSCredential -DomainCredential $DomainCredential
Add-CCSADComputerToSecurityGroup -ComputerName 'MRADTEST02' -SecurityGroupName 'TestGruppe1' -Domain 'Firmax.local' -Url $Url -CCSCredential $CCSCredential -DomainCredential $DomainCredential

$Splat = @{
ComputerName = 'MRADTEST02'
Domain = 'Firmax.local'
Url = $Url
CCSCredential = $CCSCredential
DomainCredential = $DomainCredential
}
$Result = Remove-CCSADComputer @Splat
BeforeAll {
$RootPath = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent

$Items = Get-ChildItem -Path "$RootPath\Capa.PowerShell.Module.CCS\Dev\" -Filter '*.ps1' | Where-Object { $_.Name -notlike '*Tests.ps1' }
foreach ($Item in $Items) {
Import-Module $Item.FullName -Force -ErrorAction Stop
}

# Setup test environment
$script:TestUrl = "https://$(hostname).capainstaller.com/CCSWebservice/CCS.asmx"
$script:TestDomain = 'Firmax.local'
$CredentialPath = "D:\PowerShell\Credentials\$($env:USERNAME)DomainAdminPesterTests.xml"

# Setup credentials from environment variables (GitHub secrets)
if ($env:DOMAINADMINUSERNAME -and $env:DOMAINADMINPASSWORD) {
$securePassword = ConvertTo-SecureString $env:DOMAINADMINPASSWORD -AsPlainText -Force
$script:TestDomainCredential = New-Object System.Management.Automation.PSCredential($env:DOMAINADMINUSERNAME, $securePassword)
$script:TestCCSCredential = $script:TestDomainCredential
} elseif (Test-Path -Path $CredentialPath) {
$script:TestDomainCredential = Import-Clixml -Path $CredentialPath
$script:TestCCSCredential = $script:TestDomainCredential
} else {
$script:TestDomainCredential = Get-Credential -Message 'Enter domain admin credentials for integration tests'
$script:TestCCSCredential = $script:TestDomainCredential
}

$DebugPreference = 'Continue'
$ErrorActionPreference = 'Stop'
}

Describe 'Add-CCSADComputerToSecurityGroup' -Tag 'Unit' {

Context 'Parameter Validation' {

It 'Should have mandatory ComputerName parameter' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['ComputerName'].Attributes.Mandatory | Should -Be $true
}

It 'Should have mandatory SecurityGroupName parameter' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['SecurityGroupName'].Attributes.Mandatory | Should -Be $true
}

It 'Should have mandatory Domain parameter' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['Domain'].Attributes.Mandatory | Should -Be $true
}

It 'Should have mandatory Url parameter' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['Url'].Attributes.Mandatory | Should -Be $true
}

It 'Should have mandatory CCSCredential parameter' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['CCSCredential'].Attributes.Mandatory | Should -Be $true
}

It 'Should have optional DomainCredential parameter' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['DomainCredential'].Attributes.Mandatory | Should -Be $false
}

It 'Should have optional DomainOUPath parameter' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['DomainOUPath'].Attributes.Mandatory | Should -Be $false
}

It 'Should accept array of computer names' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['ComputerName'].ParameterType.Name | Should -Be 'String[]'
}

It 'Should accept pipeline input for ComputerName' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['ComputerName'].Attributes.ValueFromPipeline | Should -Be $true
}
}

Context 'Parameter Aliases' {

It 'Should have alias "Name" for ComputerName' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['ComputerName'].Aliases | Should -Contain 'Name'
}

It 'Should have alias "Computer" for ComputerName' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['ComputerName'].Aliases | Should -Contain 'Computer'
}

It 'Should have alias "GroupName" for SecurityGroupName' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['SecurityGroupName'].Aliases | Should -Contain 'GroupName'
}

It 'Should have alias "OU" for DomainOUPath' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['DomainOUPath'].Aliases | Should -Contain 'OU'
}
}

Context 'DomainOUPath Validation' {

It 'Should accept empty DomainOUPath' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainOUPath '' -WhatIf } | Should -Not -Throw
}

It 'Should accept standard DN format' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainOUPath 'OU=Computers,DC=Firmax,DC=local' -WhatIf } | Should -Not -Throw
}

It 'Should accept DC-only format' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainOUPath 'DC=Firmax,DC=local' -WhatIf } | Should -Not -Throw
}

It 'Should accept LDAP format' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainOUPath 'LDAP://DC01.Firmax.local/OU=Computers,DC=Firmax,DC=local' -WhatIf } | Should -Not -Throw
}

It 'Should reject invalid format' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainOUPath 'InvalidPath' -WhatIf } | Should -Throw
}
}

Context 'URL Validation' {

It 'Should accept HTTPS URL' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -WhatIf } | Should -Not -Throw
}

It 'Should reject HTTP URL (only HTTPS allowed)' {
$httpUrl = $script:TestUrl -replace '^https:', 'http:'
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $httpUrl -CCSCredential $script:TestCCSCredential -WhatIf } | Should -Throw
}

It 'Should reject URL without protocol' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url 'test.com/CCS.asmx' -CCSCredential $script:TestCCSCredential -WhatIf } | Should -Throw
}
}

Context 'Domain Validation' {

It 'Should accept valid domain format' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -WhatIf } | Should -Not -Throw
}

It 'Should accept subdomain format' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain 'sub.firmax.local' -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -WhatIf } | Should -Not -Throw
}

It 'Should reject invalid domain format' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'PC01' -SecurityGroupName 'TestGroup' -Domain 'invalid_domain' -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -WhatIf } | Should -Throw
}
}

Context 'ShouldProcess Support' {

It 'Should support WhatIf' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters.ContainsKey('WhatIf') | Should -Be $true
}

It 'Should support Confirm' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters.ContainsKey('Confirm') | Should -Be $true
}
}

Context 'CmdletBinding Attributes' {

It 'Should be an advanced function' {
(Get-Command Add-CCSADComputerToSecurityGroup).CmdletBinding | Should -Be $true
}

It 'Should have SupportsShouldProcess' {
(Get-Command Add-CCSADComputerToSecurityGroup).Parameters['WhatIf'] | Should -Not -BeNullOrEmpty
}

It 'Should have OutputType defined' {
(Get-Command Add-CCSADComputerToSecurityGroup).OutputType.Name | Should -Contain 'System.String'
}
}
}

Describe 'Add-CCSADComputerToSecurityGroup - Integration Tests' -Tag 'Integration' {

Context 'Live CCS Web Service Operations' {

BeforeAll {
# Create unique test group name
$script:TestGroupName = "PesterTest_$(Get-Random -Minimum 1000 -Maximum 9999)"
$script:TestComputerName = 'PESTER-TEST-PC'
}

It 'Should connect to CCS Web Service successfully' {
{ Add-CCSADComputerToSecurityGroup -ComputerName $script:TestComputerName -SecurityGroupName $script:TestGroupName -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -WhatIf } | Should -Not -Throw
}

It 'Should add computer to security group with domain credentials' {
$result = Add-CCSADComputerToSecurityGroup -ComputerName $script:TestComputerName -SecurityGroupName $script:TestGroupName -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainCredential $script:TestDomainCredential -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
$result | Should -Not -BeNullOrEmpty
}

It 'Should process multiple computers' {
$computers = @("$script:TestComputerName`1", "$script:TestComputerName`2")
{ $computers | Add-CCSADComputerToSecurityGroup -SecurityGroupName $script:TestGroupName -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainCredential $script:TestDomainCredential -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } | Should -Not -Throw
}

It 'Should convert LDAP path format' {
$ldapPath = 'LDAP://DC01.Firmax.local/DC=Firmax,DC=local'
{ Add-CCSADComputerToSecurityGroup -ComputerName $script:TestComputerName -SecurityGroupName $script:TestGroupName -DomainOUPath $ldapPath -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainCredential $script:TestDomainCredential -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } | Should -Not -Throw
}

It 'Should add PESTER-TEST-PC to TestPester group' {
$result = Add-CCSADComputerToSecurityGroup -ComputerName 'PESTER-TEST-PC' -SecurityGroupName 'TestPester' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -DomainCredential $script:TestDomainCredential -ErrorAction Stop
$result | Should -Be 'ok'
}
}

Context 'Error Handling' {

It 'Should handle invalid credentials gracefully' {
$badCred = New-Object System.Management.Automation.PSCredential('baduser', (ConvertTo-SecureString 'badpass' -AsPlainText -Force))
{ Add-CCSADComputerToSecurityGroup -ComputerName 'TestPC' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $badCred -ErrorAction Stop } | Should -Throw
}

It 'Should handle non-existent URL gracefully' {
{ Add-CCSADComputerToSecurityGroup -ComputerName 'TestPC' -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url 'https://nonexistent.invalid/CCS.asmx' -CCSCredential $script:TestCCSCredential -ErrorAction Stop } | Should -Throw
}
}
}

Describe 'Add-CCSADComputerToSecurityGroup - Performance Tests' -Tag 'Performance' {

Context 'Pipeline Performance' {

It 'Should process pipeline input efficiently' {
$computers = 1..10 | ForEach-Object { "PC$_" }
$measure = Measure-Command {
$computers | Add-CCSADComputerToSecurityGroup -SecurityGroupName 'TestGroup' -Domain $script:TestDomain -Url $script:TestUrl -CCSCredential $script:TestCCSCredential -WhatIf -WarningAction SilentlyContinue
}
$measure.TotalSeconds | Should -BeLessThan 5
}
}
}
Loading
Loading