Skip to content

Conversation

webalexeu
Copy link

@webalexeu webalexeu commented May 16, 2025

Pull Request (PR) description

When using PasswordPass and UnsecuredJoin options or JoinReadOnly option means AD computer object has been pre-created within Active Directory prior to domain join and should not be deleted

This Pull Request (PR) fixes the following issues

Task list

  • Added an entry to the change log under the Unreleased section of the
    file CHANGELOG.md. Entry should say what was changed and how that
    affects users (if applicable), and reference the issue being resolved
    (if applicable).
  • Resource documentation added/updated in README.md.
  • Resource parameter descriptions added/updated in README.md, schema.mof
    and comment-based help.
  • Comment-based help added/updated.
  • Localization strings added/updated in all localization files as appropriate.
  • Examples appropriately added/updated.
  • Unit tests added/updated. See DSC Community Testing Guidelines.
  • Integration tests added/updated (where possible). See DSC Community Testing Guidelines.
  • New/changed code adheres to DSC Community Style Guidelines.

This change is Reviewable

@webalexeu webalexeu changed the title Computer: Remove deletion of AD computer object when using PasswordPass and UnsecuredJoin options Computer: Remove deletion of AD computer object when using PasswordPass and UnsecuredJoin options or JoinReadOnly option Jun 16, 2025
@webalexeu webalexeu marked this pull request as ready for review September 3, 2025 19:48
Copy link

coderabbitai bot commented Sep 3, 2025

Walkthrough

The changes modify the DSC_Computer resource to conditionally preserve pre-created Active Directory computer objects when using specific options (PasswordPass and UnsecuredJoin or JoinReadOnly), preventing deletion during domain join operations that expect the object to already exist.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md
Added entry documenting that the computer object is no longer deleted when PasswordPass and UnsecuredJoin options or JoinReadOnly option are used (Issue #446).
Resource Logic
source/DSCResources/DSC_Computer/DSC_Computer.psm1
Introduces conditional logic to detect precreated computer object requirements via $requiresPrecreated based on JoinReadOnly or (PasswordPass and UnsecuredJoin) options. When precreation is required and object doesn't exist, raises ObjectNotFoundException. When precreation is not required and object exists, proceeds with deletion. Includes minor comment correction.
Localization
source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1
Added new string resource ComputerObjectNotFound for localized error message when computer object is not found in domain.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as DSC Configuration
    participant Resource as DSC_Computer<br/>(Set-TargetResource)
    participant AD as Active Directory
    participant Error as Error Handler

    Caller->>Resource: Invoke Set-TargetResource
    
    Note over Resource: Detect precreated requirement<br/>($requiresPrecreated = JoinReadOnly OR<br/>(PasswordPass AND UnsecuredJoin))
    
    Resource->>AD: Query for existing computer object
    alt Object Exists
        alt Precreation NOT Required
            Resource->>AD: Delete computer object
            Resource->>Caller: ✓ Proceed with join
        else Precreation Required
            Resource->>Caller: ✓ Object exists, continue
        end
    else Object Does NOT Exist
        alt Precreation Required
            Resource->>Error: Raise ObjectNotFoundException
            Error->>Caller: ✗ Computer object not found error
        else Precreation NOT Required
            Resource->>Caller: ✓ Proceed (no deletion needed)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The changes introduce a new conditional control flow with multiple branches based on precreation detection and object existence, requiring careful verification that the option combinations and error conditions are correct. The logic is focused but depends on accurate interpretation of the PasswordPass, UnsecuredJoin, and JoinReadOnly options.

Pre-merge checks

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly identifies the resource and concisely describes the primary change of preventing deletion of the AD computer object when using the specified options, directly reflecting the main focus of the changeset.
Linked Issues Check ✅ Passed The changes implement logic to detect and preserve pre-created AD computer objects when using PasswordPass, UnsecuredJoin, or JoinReadOnly options and add corresponding error handling and localization, fully satisfying the objectives of linked issue #446.
Out of Scope Changes Check ✅ Passed All modifications are confined to adjusting the computer resource behavior for pre-created objects and updating related localization and documentation, with no unrelated or extraneous changes introduced.
Description Check ✅ Passed The description succinctly explains the rationale behind the change, clarifies that pre-created AD computer objects should not be deleted when using the specified options, and references the related issue, making it clearly relevant to the changeset.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17e10f3 and 06fe4cb.

📒 Files selected for processing (3)
  • CHANGELOG.md (1 hunks)
  • source/DSCResources/DSC_Computer/DSC_Computer.psm1 (1 hunks)
  • source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1 (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow Requirements

  • Run PowerShell script files from repository root
  • Setup build and test environment (once per pwsh session): ./build.ps1 -Tasks noop
  • Build project before running tests: ./build.ps1 -Tasks build
  • Always run tests in new pwsh session: Invoke-Pester -Path @({test paths}) -Output Detailed

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow instructions over existing code patterns
  • Follow PowerShell style and test guideline instructions strictly
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • DSC resources should always be created as class-based resources
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1
  • source/DSCResources/DSC_Computer/DSC_Computer.psm1
  • CHANGELOG.md
{**/*.ps1,**/*.psm1,**/*.psd1}

⚙️ CodeRabbit configuration file

{**/*.ps1,**/*.psm1,**/*.psd1}: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description...

Files:

  • source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1
  • source/DSCResources/DSC_Computer/DSC_Computer.psm1
source/DSCResources/**/*.psm1

⚙️ CodeRabbit configuration file

source/DSCResources/**/*.psm1: # MOF-based Desired State Configuration (DSC) Resources Guidelines

Required Functions

  • Every DSC resource must define: Get-TargetResource, Set-TargetResource, Test-TargetResource
  • Export using *-TargetResource pattern

Function Return Types

  • Get-TargetResource: Must return hashtable with all resource properties
  • Test-TargetResource: Must return boolean ($true/$false)
  • Set-TargetResource: Must not return anything (void)

Parameter Guidelines

  • Get-TargetResource: Only include parameters needed to retrieve actual current state values
  • Get-TargetResource: Remove non-mandatory parameters that are never used
  • Set-TargetResource and Test-TargetResource: Must have identical parameters
  • Set-TargetResource and Test-TargetResource: Unused mandatory parameters: Add "Not used in <function_name>" to help comment

Required Elements

  • Each function must include Write-Verbose at least once
    • Get-TargetResource: Use verbose message starting with "Getting the current state of..."
    • Set-TargetResource: Use verbose message starting with "Setting the desired state of..."
    • Test-TargetResource: Use verbose message starting with "Determining the current state of..."
  • Use localized strings for all messages (Write-Verbose, Write-Error, etc.)
  • Import localized strings using Get-LocalizedData at module top

Error Handling

Files:

  • source/DSCResources/DSC_Computer/DSC_Computer.psm1
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: # Markdown Style Guidelines

  • Wrap lines at word boundaries when over 80 characters (except tables/code blocks)
  • Use 2 spaces for indentation
  • Use '1.' for all items in ordered lists (1/1/1 numbering style)
  • Disable MD013 rule by adding a comment for tables/code blocks exceeding 80 characters
  • Empty lines required before/after code blocks and headings (except before line 1)
  • Escape backslashes in file paths only (not in code blocks)
  • Code blocks must specify language identifiers

Text Formatting

  • Parameters: bold
  • Values/literals: inline code
  • Resource/module/product names: italic
  • Commands/files/paths: inline code

Files:

  • CHANGELOG.md
CHANGELOG.md

⚙️ CodeRabbit configuration file

CHANGELOG.md: # Changelog Guidelines

  • Always update the Unreleased section in CHANGELOG.md
  • Use Keep a Changelog format
  • Describe notable changes briefly, ≤2 items per change type
  • Reference issues using format issue #<issue_number>
  • No empty lines between list items in same section
  • Skip adding entry if same change already exists in Unreleased section
  • No duplicate sections or items in Unreleased section

Files:

  • CHANGELOG.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: dsccommunity.ComputerManagementDsc (Build Package Module)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
source/DSCResources/DSC_Computer/DSC_Computer.psm1 (2)

271-271: Normalize variable casing for consistency ($Options vs $options).
PowerShell is case-insensitive, but consistent casing improves readability.

-                    if ( -not (($Options -contains 'PasswordPass' -and $options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly')))
+                    if ( -not (($Options -contains 'PasswordPass' -and $Options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly')))
...
-                    if (($Options -contains 'PasswordPass' -and $options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly'))
+                    if (($Options -contains 'PasswordPass' -and $Options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly'))

Also applies to: 280-280


265-285: DRY the option checks and make intent explicit.
Compute the “uses pre-created account” condition once and reuse.

                 # Check for existing computer object using ADSI without ActiveDirectory module
                 $computerObject = Get-ADSIComputer -Name $Name -DomainName $DomainName -Credential $Credential
+                $usesPrecreatedAccount = (
+                    ($Options -contains 'PasswordPass' -and $Options -contains 'UnsecuredJoin') -or
+                    ($Options -contains 'JoinReadOnly')
+                )
                 if ($computerObject)
                 {
-                    # UnsecuredJoin and PasswordPass options or JoinReadOnly option uses an existing machine account
-                    # to join the computer to the domain and should not be deleted before.
-                    if ( -not (($Options -contains 'PasswordPass' -and $options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly')))
+                    # UnsecuredJoin+PasswordPass or JoinReadOnly use an existing machine account; do not delete it.
+                    if (-not $usesPrecreatedAccount)
                     {
                         Remove-ADSIObject -Path $computerObject.Path -Credential $Credential
                         Write-Verbose -Message ($script:localizedData.DeletedExistingComputerObject -f $Name, $computerObject.Path)
                     }
                 }
                 else
                 {
-                    # Check if the computer object exists in the domain when using UnsecuredJoin and PasswordPass options or JoinReadOnly option 
-                    if (($Options -contains 'PasswordPass' -and $options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly'))
+                    # Require a pre-created computer object for UnsecuredJoin+PasswordPass or JoinReadOnly.
+                    if ($usesPrecreatedAccount)
                     {
                         $errorMessage = $script:localizedData.ComputerObjectNotFound -f $Name,$DomainName
                         New-ObjectNotFoundException -Message $errorMessage
                     }
                 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d3f29e4 and 0db4bd1.

📒 Files selected for processing (3)
  • CHANGELOG.md (1 hunks)
  • source/DSCResources/DSC_Computer/DSC_Computer.psm1 (1 hunks)
  • source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1 (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run in PowerShell, from repository root
  • Build before running tests: .\build.ps1 -Tasks build
  • Always run tests in new PowerShell session: Invoke-Pester -Path @({test paths}) -Output Detailed

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1
  • source/DSCResources/DSC_Computer/DSC_Computer.psm1
  • CHANGELOG.md
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • OUTPUTS: Lis...

Files:

  • source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1
  • source/DSCResources/DSC_Computer/DSC_Computer.psm1
source/DSCResources/**/*.psm1

⚙️ CodeRabbit configuration file

source/DSCResources/**/*.psm1: # MOF-based Desired State Configuration (DSC) Resources Guidelines

Required Functions

  • Every DSC resource must define: Get-TargetResource, Set-TargetResource, Test-TargetResource
  • Export using *-TargetResource pattern

Function Return Types

  • Get-TargetResource: Must return hashtable with all resource properties
  • Test-TargetResource: Must return boolean ($true/$false)
  • Set-TargetResource: Must not return anything (void)

Parameter Guidelines

  • Get-TargetResource: Only include parameters needed to retrieve actual current state values
  • Get-TargetResource: Remove non-mandatory parameters that are never used
  • Set-TargetResource and Test-TargetResource: Must have identical parameters
  • Set-TargetResource and Test-TargetResource: Unused mandatory parameters: Add "Not used in <function_name>" to help comment

Required Elements

  • Each function must include Write-Verbose at least once
    • Get-TargetResource: Use verbose message starting with "Getting the current state of..."
    • Set-TargetResource: Use verbose message starting with "Setting the desired state of..."
    • Test-TargetResource: Use verbose message starting with "Determining the current state of..."
  • Use localized strings for all messages (Write-Verbose, Write-Error, etc.)
  • Import localized strings using Get-LocalizedData at module top

Error Handling

Files:

  • source/DSCResources/DSC_Computer/DSC_Computer.psm1
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: # Markdown Style Guidelines

  • Wrap lines at word boundaries when over 80 characters (except tables/code blocks)
  • Use 2 spaces for indentation
  • Use '1.' for all items in ordered lists (1/1/1 numbering style)
  • Disable MD013 rule by adding a comment for tables/code blocks exceeding 80 characters
  • Empty lines required before/after code blocks and headings (except before line 1)
  • Escape backslashes in file paths only (not in code blocks)
  • Code blocks must specify language identifiers

Text Formatting

  • Parameters: bold
  • Values/literals: inline code
  • Resource/module/product names: italic
  • Commands/files/paths: inline code

Files:

  • CHANGELOG.md
CHANGELOG.md

⚙️ CodeRabbit configuration file

CHANGELOG.md: # Changelog Guidelines

  • Always update the Unreleased section in CHANGELOG.md
  • Use Keep a Changelog format
  • Describe notable changes briefly, ≤2 items per change type
  • Reference issues using format issue #<issue_number>
  • No empty lines between list items in same section
  • Do not add item if there are already an existing item for the same change

Files:

  • CHANGELOG.md
🪛 markdownlint-cli2 (0.17.2)
CHANGELOG.md

17-17: Line length
Expected: 80; Actual: 108

(MD013, line-length)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: dsccommunity.ComputerManagementDsc (Build Package Module)
🔇 Additional comments (2)
source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1 (1)

20-20: LGTM: New localized error string added and consistent with existing keys.
Message text is clear and parameterized as required.

source/DSCResources/DSC_Computer/DSC_Computer.psm1 (1)

265-276: LGTM: Correctly avoids deleting pre-created AD computer objects for specific join modes.
Logic aligns with Add-Computer semantics for PasswordPass+UnsecuredJoin and JoinReadOnly.

Comment on lines +17 to +18
- Remove deletion of computer object when PasswordPass and UnsecuredJoin options are used in DSC_Computer.
Fixes [Issue #446](https://github.com/dsccommunity/ComputerManagementDsc/issues/446).
Copy link

@coderabbitai coderabbitai bot Sep 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Include JoinReadOnly and wrap long line to satisfy MD013.
The code change also covers JoinReadOnly; reflect that in the changelog. Also wrap to ≤80 chars.

-  - Remove deletion of computer object when PasswordPass and UnsecuredJoin options are used in DSC_Computer.
+  - Remove deletion of computer object when PasswordPass and UnsecuredJoin
+    options, or JoinReadOnly option, are used in DSC_Computer.
   Fixes [Issue #446](https://github.com/dsccommunity/ComputerManagementDsc/issues/446).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Remove deletion of computer object when PasswordPass and UnsecuredJoin options are used in DSC_Computer.
Fixes [Issue #446](https://github.com/dsccommunity/ComputerManagementDsc/issues/446).
- Remove deletion of computer object when PasswordPass and UnsecuredJoin
options, or JoinReadOnly option, are used in DSC_Computer.
Fixes [Issue #446](https://github.com/dsccommunity/ComputerManagementDsc/issues/446).
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

17-17: Line length
Expected: 80; Actual: 108

(MD013, line-length)

🤖 Prompt for AI Agents
In CHANGELOG.md around lines 17 to 18, update the entry to mention that the
removal of deletion of the computer object also applies when JoinReadOnly is
used (not just PasswordPass and UnsecuredJoin), and reflow the line so it is
wrapped at or under 80 characters per line to satisfy MD013; keep the same
wording and link to Issue #446 but split into multiple lines as needed for the
80-character limit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@webalexeu can you resolve this?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather see this resolved at the same time as a test is commited.

Comment on lines 265 to 285
# Check for existing computer object using ADSI without ActiveDirectory module
$computerObject = Get-ADSIComputer -Name $Name -DomainName $DomainName -Credential $Credential

if ($computerObject)
{
Remove-ADSIObject -Path $computerObject.Path -Credential $Credential
Write-Verbose -Message ($script:localizedData.DeletedExistingComputerObject -f $Name, $computerObject.Path)
# UnsecuredJoin and PasswordPass options or JoinReadOnly option uses an existing machine account
# to join the computer to the domain and should not be deleted before.
if ( -not (($Options -contains 'PasswordPass' -and $options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly')))
{
Remove-ADSIObject -Path $computerObject.Path -Credential $Credential
Write-Verbose -Message ($script:localizedData.DeletedExistingComputerObject -f $Name, $computerObject.Path)
}
}
else
{
# Check if the computer object exists in the domain when using UnsecuredJoin and PasswordPass options or JoinReadOnly option
if (($Options -contains 'PasswordPass' -and $options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly'))
{
$errorMessage = $script:localizedData.ComputerObjectNotFound -f $Name,$DomainName
New-ObjectNotFoundException -Message $errorMessage
}
}
Copy link

@coderabbitai coderabbitai bot Sep 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Add unit tests for both branches (found vs. not found) under the new options.
Cover: 1) no deletion when object exists and options require pre-created account; 2) ObjectNotFound exception when missing.


🏁 Script executed:

#!/bin/bash
# Locate tests covering the new behaviors
rg -nC2 -g 'tests/**' -e "ComputerObjectNotFound|JoinReadOnly|UnsecuredJoin|PasswordPass"

# Ensure tests assert deletion behavior paths as expected
rg -nC3 -g 'tests/**' -e "DeletedExistingComputerObject|Remove-ADSIObject"

Length of output: 12903


Add missing unit tests for ADSI deletion logic under the new options.

  • Stub Get-ADSIComputer to return a non-null object and assert Remove-ADSIObject is not invoked when Options contains PasswordPass & UnsecuredJoin or JoinReadOnly.
  • Stub Get-ADSIComputer to return $null and assert New-ObjectNotFoundException is thrown for those same option combinations.
🤖 Prompt for AI Agents
In source/DSCResources/DSC_Computer/DSC_Computer.psm1 around lines 265-285, add
unit tests that cover the ADSI deletion logic for the PasswordPass+UnsecuredJoin
and JoinReadOnly option combinations: create one test that stubs
Get-ADSIComputer to return a non-null object and asserts Remove-ADSIObject is
NOT invoked when Options contains both 'PasswordPass' and 'UnsecuredJoin' and
another test that stubs Get-ADSIComputer to return $null and asserts
New-ObjectNotFoundException is thrown for the same option combinations (repeat
for the 'JoinReadOnly' scenario); ensure the tests set Options appropriately,
inject a stubbed Credential/DomainName if required, and verify behavior with
appropriate mocks/spies for Remove-ADSIObject and the exception helper.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@webalexeu can you add a unit test to handle the new code path that throws. I tried to get the AI to add it but that failed big time. 😄

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a unit test to cover the new code paths.

Copy link

codecov bot commented Sep 4, 2025

Codecov Report

❌ Patch coverage is 71.42857% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 86%. Comparing base (17e10f3) to head (06fe4cb).

Files with missing lines Patch % Lines
source/DSCResources/DSC_Computer/DSC_Computer.psm1 71% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@         Coverage Diff         @@
##           main   #447   +/-   ##
===================================
- Coverage    86%    86%   -1%     
===================================
  Files        21     21           
  Lines      2083   2088    +5     
===================================
+ Hits       1805   1808    +3     
- Misses      278    280    +2     
Files with missing lines Coverage Δ
source/DSCResources/DSC_Computer/DSC_Computer.psm1 89% <71%> (-1%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This comment was marked as resolved.

This comment was marked as resolved.

This comment was marked as resolved.

This comment was marked as resolved.

@johlju johlju added the waiting for code fix A review left open comments, and the pull request is waiting for changes to be pushed by the author. label Sep 4, 2025
Copy link
Member

@johlju johlju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johlju reviewed 1 of 3 files at r1, 2 of 2 files at r4, all commit messages.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @webalexeu)

Comment on lines +17 to +18
- Remove deletion of computer object when PasswordPass and UnsecuredJoin options are used in DSC_Computer.
Fixes [Issue #446](https://github.com/dsccommunity/ComputerManagementDsc/issues/446).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather see this resolved at the same time as a test is commited.

Comment on lines 265 to 285
# Check for existing computer object using ADSI without ActiveDirectory module
$computerObject = Get-ADSIComputer -Name $Name -DomainName $DomainName -Credential $Credential

if ($computerObject)
{
Remove-ADSIObject -Path $computerObject.Path -Credential $Credential
Write-Verbose -Message ($script:localizedData.DeletedExistingComputerObject -f $Name, $computerObject.Path)
# UnsecuredJoin and PasswordPass options or JoinReadOnly option uses an existing machine account
# to join the computer to the domain and should not be deleted before.
if ( -not (($Options -contains 'PasswordPass' -and $options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly')))
{
Remove-ADSIObject -Path $computerObject.Path -Credential $Credential
Write-Verbose -Message ($script:localizedData.DeletedExistingComputerObject -f $Name, $computerObject.Path)
}
}
else
{
# Check if the computer object exists in the domain when using UnsecuredJoin and PasswordPass options or JoinReadOnly option
if (($Options -contains 'PasswordPass' -and $options -contains 'UnsecuredJoin') -or ($Options -contains 'JoinReadOnly'))
{
$errorMessage = $script:localizedData.ComputerObjectNotFound -f $Name,$DomainName
New-ObjectNotFoundException -Message $errorMessage
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a unit test to cover the new code paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting for code fix A review left open comments, and the pull request is waiting for changes to be pushed by the author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Computer: AD object should not be deleted when using PasswordPass and UnsecuredJoin options or JoinReadOnly option

2 participants