en-US/about_PSUKG_BulkOperations.help.txt

TOPIC
    about_PSUKG_BulkOperations

SHORT DESCRIPTION
    Explains bulk operations and asynchronous processing in the PSUKG module.

LONG DESCRIPTION
    The PSUKG module supports bulk operations for creating, updating, and
    deleting multiple employees or users in a single API call. Bulk operations
    are processed asynchronously, and the module provides tools for tracking
    their status and retrieving results.

  Why Use Bulk Operations
    Performance:
        Bulk operations are significantly faster than individual API calls.
        Creating 100 employees individually = 100 API calls
        Creating 100 employees in bulk = 1 API call + status checks

    Atomicity:
        All operations in a bulk request are validated before execution.
        If validation fails, no changes are made.

    Efficiency:
        Reduces network overhead and API rate limiting concerns.

  Bulk Operation Flow
    1. Submit bulk request with Invoke-UKGEmployeeBulk or Invoke-UKGUserBulk
    2. API validates the request and returns a bulk operation ID
    3. API processes the operations asynchronously
    4. Poll status with Get-UKGEmployeeBulkStatus or Get-UKGUserBulkStatus
    5. Retrieve results when status is "completed" or "failed"

  Supported Bulk Operations
    Employees (Invoke-UKGEmployeeBulk):
        -Create: Create multiple employees
        -Update: Update multiple employees
        -Delete: Delete multiple employees

    Users (Invoke-UKGUserBulk):
        -Create: Create multiple users
        -Update: Update multiple users
        -Delete: Delete multiple users

  Operation Modes
    Asynchronous (Default):
        Submits the request and returns immediately with an operation ID.
        You manually check status using Get-UKG*BulkStatus.

        $bulkOp = Invoke-UKGEmployeeBulk -Create -Employees $data
        # Do other work...
        $status = Get-UKGEmployeeBulkStatus -Id $bulkOp.id

    Synchronous (-WaitForCompletion):
        Submits the request and automatically polls until completion.
        Returns final results when done.

        $result = Invoke-UKGEmployeeBulk -Create -Employees $data -WaitForCompletion

  Data Format
    Bulk operations accept arrays of hashtables representing resources:

    Employees:
        $employees = @(
            @{
                email = "john.doe@company.com"
                first_name = "John"
                last_name = "Doe"
                employee_number = "E001"
                hire_date = "2024-01-15"
            },
            @{
                email = "jane.smith@company.com"
                first_name = "Jane"
                last_name = "Smith"
                employee_number = "E002"
                hire_date = "2024-01-20"
            }
        )

    Users:
        $users = @(
            @{
                email = "admin1@company.com"
                first_name = "Admin"
                last_name = "One"
                role_id = "role123"
            },
            @{
                email = "admin2@company.com"
                first_name = "Admin"
                last_name = "Two"
                role_id = "role123"
            }
        )

  Status Lifecycle
    pending:
        Operation has been submitted and is queued for processing.

    processing:
        Operation is currently being executed.

    completed:
        Operation finished successfully.
        Check successful_count and failed_count for details.

    failed:
        Operation failed before completion.
        Check error field for details.

  Result Information
    Completed bulk operations provide:

    status:
        Final status (completed or failed)

    successful_count:
        Number of resources successfully processed

    failed_count:
        Number of resources that failed processing

    results:
        Array of result objects with details for each resource:
        - success: Boolean indicating success/failure
        - id: Resource ID (if successful)
        - error: Error details (if failed)

  Polling Strategies
    Manual Polling:
        # Submit operation
        $bulkOp = Invoke-UKGEmployeeBulk -Create -Employees $data

        # Poll until complete
        do {
            Start-Sleep -Seconds 2
            $status = Get-UKGEmployeeBulkStatus -Id $bulkOp.id
            Write-Host "Status: $($status.status)"
        } while ($status.status -in @('pending', 'processing'))

        # Check results
        if ($status.status -eq 'completed') {
            Write-Host "Success: $($status.successful_count)"
            Write-Host "Failed: $($status.failed_count)"
        }

    Automatic Polling (-WaitForCompletion):
        $result = Invoke-UKGEmployeeBulk -Create -Employees $data -WaitForCompletion

        if ($result.status -eq 'completed') {
            Write-Host "Success: $($result.successful_count)"
        }

  Error Handling
    Validation Errors:
        If the bulk request is invalid (wrong format, missing required fields),
        the cmdlet throws an error immediately.

    Processing Errors:
        Some resources may succeed while others fail. Check results array:

        $result = Invoke-UKGEmployeeBulk -Create -Employees $data -WaitForCompletion

        foreach ($res in $result.results) {
            if ($res.success) {
                Write-Host "Created employee: $($res.id)"
            } else {
                Write-Warning "Failed: $($res.error.message)"
            }
        }

  Best Practices
    Batch Size:
        Keep batches under 1000 items for optimal performance.
        UKG API may have limits on batch size.

    Validation:
        Validate data before submitting to avoid partial failures:
        - Check required fields
        - Verify email formats
        - Ensure unique identifiers

    Error Recovery:
        Save failed items and retry separately:

        $failed = $result.results | Where-Object { -not $_.success }
        if ($failed) {
            $failed | Export-Csv -Path "failed_employees.csv"
        }

    Idempotency:
        Use external IDs or employee numbers to make operations idempotent.
        This allows safe retries without duplicates.

    Progress Indication:
        For large operations, provide user feedback:

        Write-Progress -Activity "Creating Employees" -Status "Processing..."
        $result = Invoke-UKGEmployeeBulk -Create -Employees $data -WaitForCompletion
        Write-Progress -Activity "Creating Employees" -Completed

  Performance Comparison
    Individual Operations:
        # Slow: 100 API calls
        $employees = Import-Csv "employees.csv"
        foreach ($emp in $employees) {
            New-UKGEmployee -Email $emp.email -FirstName $emp.first_name `
                           -LastName $emp.last_name -EmployeeNumber $emp.employee_number
        }
        # Time: ~100-200 seconds

    Bulk Operation:
        # Fast: 1 API call + status checks
        $employees = Import-Csv "employees.csv" | ForEach-Object {
            @{
                email = $_.email
                first_name = $_.first_name
                last_name = $_.last_name
                employee_number = $_.employee_number
            }
        }
        $result = Invoke-UKGEmployeeBulk -Create -Employees $employees -WaitForCompletion
        # Time: ~10-20 seconds

EXAMPLES
  Example 1: Simple Bulk Create with Automatic Completion
    # Create multiple employees and wait for completion
    $employees = @(
        @{ email = "emp1@company.com"; first_name = "John"; last_name = "Doe"; employee_number = "E001" },
        @{ email = "emp2@company.com"; first_name = "Jane"; last_name = "Smith"; employee_number = "E002" }
    )

    $result = Invoke-UKGEmployeeBulk -Create -Employees $employees -WaitForCompletion

    Write-Host "Successfully created $($result.successful_count) employees"
    Write-Host "Failed to create $($result.failed_count) employees"

  Example 2: Manual Status Polling
    # Submit bulk operation
    $employees = @(
        @{ email = "emp1@company.com"; first_name = "John"; last_name = "Doe"; employee_number = "E001" }
    )
    $bulkOp = Invoke-UKGEmployeeBulk -Create -Employees $employees

    Write-Host "Bulk operation submitted: $($bulkOp.id)"

    # Poll status
    do {
        Start-Sleep -Seconds 2
        $status = Get-UKGEmployeeBulkStatus -Id $bulkOp.id
        Write-Host "Status: $($status.status)"
    } while ($status.status -in @('pending', 'processing'))

    # Display results
    if ($status.status -eq 'completed') {
        Write-Host "Operation completed successfully"
    }

  Example 3: Bulk Update from CSV
    # Import employee updates from CSV
    $updates = Import-Csv "employee_updates.csv" | ForEach-Object {
        @{
            id = $_.employee_id
            title = $_.new_title
            department = $_.new_department
        }
    }

    # Submit bulk update
    $result = Invoke-UKGEmployeeBulk -Update -Employees $updates -WaitForCompletion

    Write-Host "Updated $($result.successful_count) employees"

  Example 4: Error Handling and Retry
    # Attempt bulk create
    $employees = Import-Csv "new_employees.csv" | ForEach-Object {
        @{
            email = $_.email
            first_name = $_.first_name
            last_name = $_.last_name
            employee_number = $_.employee_number
        }
    }

    $result = Invoke-UKGEmployeeBulk -Create -Employees $employees -WaitForCompletion

    # Check for failures
    $failed = $result.results | Where-Object { -not $_.success }

    if ($failed) {
        Write-Warning "Some employees failed to create"

        # Export failed items for review
        $failedEmployees = foreach ($failure in $failed) {
            $index = [array]::IndexOf($result.results, $failure)
            [PSCustomObject]@{
                Email = $employees[$index].email
                Error = $failure.error.message
            }
        }

        $failedEmployees | Export-Csv -Path "failed_creates.csv" -NoTypeInformation
        Write-Host "Failed employees exported to failed_creates.csv"
    }

  Example 5: Large Dataset with Progress
    # Process large CSV file in batches
    $allEmployees = Import-Csv "large_employee_list.csv"
    $batchSize = 500
    $totalBatches = [Math]::Ceiling($allEmployees.Count / $batchSize)

    for ($i = 0; $i -lt $totalBatches; $i++) {
        Write-Progress -Activity "Creating Employees" `
                      -Status "Batch $($i+1) of $totalBatches" `
                      -PercentComplete (($i / $totalBatches) * 100)

        $start = $i * $batchSize
        $batch = $allEmployees[$start..($start + $batchSize - 1)] | ForEach-Object {
            @{
                email = $_.email
                first_name = $_.first_name
                last_name = $_.last_name
                employee_number = $_.employee_number
            }
        }

        $result = Invoke-UKGEmployeeBulk -Create -Employees $batch -WaitForCompletion
        Write-Host "Batch $($i+1): $($result.successful_count) created, $($result.failed_count) failed"
    }

    Write-Progress -Activity "Creating Employees" -Completed

  Example 6: Bulk User Creation
    # Create multiple users
    $users = @(
        @{ email = "admin1@company.com"; first_name = "Admin"; last_name = "One"; role_id = "role123" },
        @{ email = "admin2@company.com"; first_name = "Admin"; last_name = "Two"; role_id = "role123" }
    )

    $result = Invoke-UKGUserBulk -Create -Users $users -WaitForCompletion

    Write-Host "Created $($result.successful_count) users"

  Example 7: Bulk Delete with Confirmation
    # Get employees to delete
    $employeesToDelete = Search-UKGEmployee -Filter @{
        status = @{ eq = "terminated" }
        termination_date = @{ lte = "2023-12-31" }
    } -All

    # Prepare delete data
    $deleteData = $employeesToDelete | ForEach-Object {
        @{ id = $_.id }
    }

    # Confirm before delete
    $confirm = Read-Host "Delete $($deleteData.Count) employees? (yes/no)"
    if ($confirm -eq "yes") {
        $result = Invoke-UKGEmployeeBulk -Delete -Employees $deleteData -WaitForCompletion
        Write-Host "Deleted $($result.successful_count) employees"
    }

KEYWORDS
    Bulk, Asynchronous, Batch, Import, Create, Update, Delete

SEE ALSO
    about_PSUKG
    Invoke-UKGEmployeeBulk
    Get-UKGEmployeeBulkStatus
    Invoke-UKGUserBulk
    Get-UKGUserBulkStatus