Explore CSV (Comma-Separated Values) file format essentials, tools, and best practices. Learn how to create, edit, and manage CSV files for data storage, analysis, and seamless data transfer between applications. Discover tips for efficient data handling, conversion techniques, and troubleshooting common CSV issues.

Tag Archive for: CSV

CSV File Validator Tool

<#
.SYNOPSIS
CSV File Validator Tool

.DESCRIPTION
This script provides a tool to validate CSV files, check for structural issues,
analyze data types, and provide detailed information about the CSV content.

.NOTES
File Name      : CSVValidator.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\CSVValidator.ps1
#>

function Show-Menu {
    Clear-Host
    Write-Host "=== CSV File Validator Tool ===" -ForegroundColor Cyan
    Write-Host "1. Validate CSV File"
    Write-Host "2. Analyze CSV Structure"
    Write-Host "3. Check for Data Inconsistencies"
    Write-Host "4. Generate CSV Summary"
    Write-Host "5. Compare Two CSV Files"
    Write-Host "6. Exit"
}

function Validate-CSVFile {
    $filePath = Read-Host "Enter the path to the CSV file"
    if (-not (Test-Path $filePath)) {
        Write-Host "File not found." -ForegroundColor Red
        return
    }

    try {
        $csv = Import-Csv $filePath
        $rowCount = $csv.Count
        $columnCount = ($csv | Get-Member -MemberType NoteProperty).Count

        Write-Host "CSV is valid." -ForegroundColor Green
        Write-Host "Number of rows: $rowCount"
        Write-Host "Number of columns: $columnCount"

        $headers = ($csv | Get-Member -MemberType NoteProperty).Name
        Write-Host "Headers: $($headers -join ', ')"

        $size = (Get-Item $filePath).Length
        Write-Host "File Size: $size bytes"
    }
    catch {
        Write-Host "Invalid CSV. Error details:" -ForegroundColor Red
        Write-Host $_.Exception.Message
    }
}

function Analyze-CSVStructure {
    $filePath = Read-Host "Enter the path to the CSV file"
    if (-not (Test-Path $filePath)) {
        Write-Host "File not found." -ForegroundColor Red
        return
    }

    try {
        $csv = Import-Csv $filePath
        $headers = ($csv | Get-Member -MemberType NoteProperty).Name

        Write-Host "CSV Structure Analysis:" -ForegroundColor Yellow
        foreach ($header in $headers) {
            $values = $csv.$header | Where-Object { $_ -ne "" }
            $dataType = Guess-DataType $values
            $uniqueValues = ($values | Select-Object -Unique).Count
            $nullCount = ($csv.$header | Where-Object { $_ -eq "" }).Count

            Write-Host "`nColumn: $header"
            Write-Host "  Data Type: $dataType"
            Write-Host "  Unique Values: $uniqueValues"
            Write-Host "  Null/Empty Values: $nullCount"
            Write-Host "  Sample Values: $($values | Select-Object -First 5 -Unique)"
        }
    }
    catch {
        Write-Host "Error analyzing CSV structure: $_" -ForegroundColor Red
    }
}

function Guess-DataType($values) {
    $sampleSize = [Math]::Min($values.Count, 100)
    $sample = $values | Select-Object -First $sampleSize

    $isNumeric = $sample | ForEach-Object { $_ -as [double] } | Where-Object { $_ -ne $null }
    $isDate = $sample | ForEach-Object { $_ -as [datetime] } | Where-Object { $_ -ne $null }

    if ($isNumeric.Count -eq $sampleSize) { return "Numeric" }
    elseif ($isDate.Count -eq $sampleSize) { return "Date" }
    else { return "String" }
}

function Check-DataInconsistencies {
    $filePath = Read-Host "Enter the path to the CSV file"
    if (-not (Test-Path $filePath)) {
        Write-Host "File not found." -ForegroundColor Red
        return
    }

    try {
        $csv = Import-Csv $filePath
        $headers = ($csv | Get-Member -MemberType NoteProperty).Name

        Write-Host "Checking for Data Inconsistencies:" -ForegroundColor Yellow
        foreach ($header in $headers) {
            $values = $csv.$header
            $dataType = Guess-DataType $values

            $inconsistencies = @()
            switch ($dataType) {
                "Numeric" {
                    $inconsistencies = $values | Where-Object { $_ -ne "" -and ($_ -as [double]) -eq $null }
                }
                "Date" {
                    $inconsistencies = $values | Where-Object { $_ -ne "" -and ($_ -as [datetime]) -eq $null }
                }
            }

            if ($inconsistencies.Count -gt 0) {
                Write-Host "`nInconsistencies found in column '$header' (Expected $dataType):"
                Write-Host ($inconsistencies | Select-Object -First 5) -ForegroundColor Red
                if ($inconsistencies.Count -gt 5) {
                    Write-Host "... and $($inconsistencies.Count - 5) more."
                }
            }
        }
    }
    catch {
        Write-Host "Error checking data inconsistencies: $_" -ForegroundColor Red
    }
}

function Generate-CSVSummary {
    $filePath = Read-Host "Enter the path to the CSV file"
    if (-not (Test-Path $filePath)) {
        Write-Host "File not found." -ForegroundColor Red
        return
    }

    try {
        $csv = Import-Csv $filePath
        $rowCount = $csv.Count
        $headers = ($csv | Get-Member -MemberType NoteProperty).Name

        Write-Host "CSV Summary:" -ForegroundColor Yellow
        Write-Host "File: $filePath"
        Write-Host "Total Rows: $rowCount"
        Write-Host "Total Columns: $($headers.Count)"
        Write-Host "`nColumn Summary:"

        foreach ($header in $headers) {
            $values = $csv.$header
            $nonEmptyValues = $values | Where-Object { $_ -ne "" }
            $uniqueValues = ($nonEmptyValues | Select-Object -Unique).Count
            $nullCount = ($values | Where-Object { $_ -eq "" }).Count
            $dataType = Guess-DataType $nonEmptyValues

            Write-Host "`n$header:"
            Write-Host "  Data Type: $dataType"
            Write-Host "  Unique Values: $uniqueValues"
            Write-Host "  Null/Empty Count: $nullCount"
            Write-Host "  Fill Rate: $([math]::Round(($rowCount - $nullCount) / $rowCount * 100, 2))%"

            if ($dataType -eq "Numeric") {
                $numericValues = $nonEmptyValues | ForEach-Object { $_ -as [double] }
                $min = ($numericValues | Measure-Object -Minimum).Minimum
                $max = ($numericValues | Measure-Object -Maximum).Maximum
                $avg = ($numericValues | Measure-Object -Average).Average
                Write-Host "  Min: $min"
                Write-Host "  Max: $max"
                Write-Host "  Average: $([math]::Round($avg, 2))"
            }
        }
    }
    catch {
        Write-Host "Error generating CSV summary: $_" -ForegroundColor Red
    }
}

function Compare-CSVFiles {
    $filePath1 = Read-Host "Enter the path to the first CSV file"
    $filePath2 = Read-Host "Enter the path to the second CSV file"

    if (-not (Test-Path $filePath1) -or -not (Test-Path $filePath2)) {
        Write-Host "One or both files not found." -ForegroundColor Red
        return
    }

    try {
        $csv1 = Import-Csv $filePath1
        $csv2 = Import-Csv $filePath2

        $headers1 = ($csv1 | Get-Member -MemberType NoteProperty).Name
        $headers2 = ($csv2 | Get-Member -MemberType NoteProperty).Name

        Write-Host "Comparing CSV Files:" -ForegroundColor Yellow
        Write-Host "File 1: $filePath1"
        Write-Host "File 2: $filePath2"

        Write-Host "`nColumn Comparison:"
        $commonHeaders = $headers1 | Where-Object { $headers2 -contains $_ }
        $uniqueHeaders1 = $headers1 | Where-Object { $headers2 -notcontains $_ }
        $uniqueHeaders2 = $headers2 | Where-Object { $headers1 -notcontains $_ }

        Write-Host "Common Columns: $($commonHeaders -join ', ')"
        Write-Host "Columns only in File 1: $($uniqueHeaders1 -join ', ')"
        Write-Host "Columns only in File 2: $($uniqueHeaders2 -join ', ')"

        Write-Host "`nRow Count Comparison:"
        Write-Host "File 1 Row Count: $($csv1.Count)"
        Write-Host "File 2 Row Count: $($csv2.Count)"

        Write-Host "`nData Comparison for Common Columns:"
        foreach ($header in $commonHeaders) {
            $diff = Compare-Object $csv1.$header $csv2.$header
            if ($diff) {
                Write-Host "Differences found in column '$header':"
                Write-Host "  Values only in File 1: $($diff | Where-Object { $_.SideIndicator -eq '<=' } | Select-Object -ExpandProperty InputObject)"
                Write-Host "  Values only in File 2: $($diff | Where-Object { $_.SideIndicator -eq '=>' } | Select-Object -ExpandProperty InputObject)"
            }
            else {
                Write-Host "No differences found in column '$header'"
            }
        }
    }
    catch {
        Write-Host "Error comparing CSV files: $_" -ForegroundColor Red
    }
}

# Main program loop
do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-6)"

    switch ($choice) {
        "1" { Validate-CSVFile }
        "2" { Analyze-CSVStructure }
        "3" { Check-DataInconsistencies }
        "4" { Generate-CSVSummary }
        "5" { Compare-CSVFiles }
        "6" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "6") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "6")

This CSV File Validator Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to perform various CSV-related tasks:
    • Validate CSV files and provide basic statistics
    • Analyze and display the structure of CSV files
    • Check for data inconsistencies
    • Generate a comprehensive summary of the CSV content
    • Compare two CSV files

Key features:

  1. CSV Validation:
    • Checks if the CSV is valid and can be parsed
    • Provides row count, column count, headers, and file size
  2. CSV Structure Analysis:
    • Analyzes each column for data type, unique values, and null/empty values
    • Provides sample values for each column
  3. Data Inconsistency Check:
    • Identifies values that don’t match the expected data type for each column
  4. CSV Summary Generation:
    • Provides a comprehensive summary of the CSV, including data types, unique values, fill rates, and basic statistics for numeric columns
  5. CSV Comparison:
    • Compares two CSV files for structural differences and data discrepancies

This tool is particularly useful for:

  • Data analysts validating CSV datasets
  • QA engineers checking CSV file integrity
  • Developers working with CSV data imports/exports
  • Anyone needing to quickly analyze or compare CSV files

To use this script effectively:

  1. Run the script in PowerShell
  2. Use the menu options to select the desired function
  3. Provide the path to the CSV file(s) when prompted
  4. Review the output for validation results, structure analysis, inconsistencies, summaries, or file comparisons

This script provides a comprehensive set of tools for working with CSV files, making it easier to validate, understand, and compare CSV data without having to manually inspect the files or use multiple tools.

CSV Generator Tool

<#
.SYNOPSIS
CSV Generator Tool

.DESCRIPTION
This script provides an interactive tool to create CSV structures, add columns and rows,
and export the resulting CSV to a file.

.NOTES
File Name      : CSVGenerator.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\CSVGenerator.ps1
#>

# Global variables
$script:csvData = @()
$script:columns = @()
$script:csvFilePath = "$env:USERPROFILE\Desktop\Generated_CSV_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"

function Show-Menu {
    Clear-Host
    Write-Host "=== CSV Generator Tool ===" -ForegroundColor Cyan
    Write-Host "1. Define Columns"
    Write-Host "2. Add Row"
    Write-Host "3. View Current CSV Structure"
    Write-Host "4. Import Data from JSON"
    Write-Host "5. Generate Sample Data"
    Write-Host "6. Export CSV to File"
    Write-Host "7. Exit"
}

function Define-Columns {
    $script:columns = @()
    do {
        $columnName = Read-Host "Enter column name (or press Enter to finish)"
        if ($columnName -ne "") {
            $script:columns += $columnName
        }
    } while ($columnName -ne "")

    Write-Host "Columns defined: $($script:columns -join ', ')" -ForegroundColor Green
}

function Add-Row {
    if ($script:columns.Count -eq 0) {
        Write-Host "Please define columns first." -ForegroundColor Yellow
        return
    }

    $row = @{}
    foreach ($column in $script:columns) {
        $value = Read-Host "Enter value for '$column'"
        $row[$column] = $value
    }

    $script:csvData += [PSCustomObject]$row
    Write-Host "Row added successfully." -ForegroundColor Green
}

function View-CurrentCSV {
    if ($script:csvData.Count -eq 0) {
        Write-Host "No data available. Please add some rows first." -ForegroundColor Yellow
        return
    }

    $script:csvData | Format-Table -AutoSize
}

function Import-FromJSON {
    $jsonPath = Read-Host "Enter the path to the JSON file"
    if (-not (Test-Path $jsonPath)) {
        Write-Host "File not found." -ForegroundColor Red
        return
    }

    try {
        $jsonData = Get-Content $jsonPath -Raw | ConvertFrom-Json
        
        if ($jsonData -is [Array]) {
            $script:columns = $jsonData[0].PSObject.Properties.Name
            $script:csvData = $jsonData
        }
        else {
            $script:columns = $jsonData.PSObject.Properties.Name
            $script:csvData = @($jsonData)
        }

        Write-Host "Data imported successfully from JSON." -ForegroundColor Green
        Write-Host "Columns: $($script:columns -join ', ')" -ForegroundColor Green
        Write-Host "Number of rows: $($script:csvData.Count)" -ForegroundColor Green
    }
    catch {
        Write-Host "Error importing JSON: $_" -ForegroundColor Red
    }
}

function Generate-SampleData {
    if ($script:columns.Count -eq 0) {
        Write-Host "Please define columns first." -ForegroundColor Yellow
        return
    }

    $rowCount = Read-Host "Enter the number of sample rows to generate"
    if (-not [int]::TryParse($rowCount, [ref]$null)) {
        Write-Host "Invalid number. Please enter a valid integer." -ForegroundColor Red
        return
    }

    $script:csvData = @()

    for ($i = 1; $i -le [int]$rowCount; $i++) {
        $row = @{}
        foreach ($column in $script:columns) {
            $row[$column] = Get-SampleValue $column $i
        }
        $script:csvData += [PSCustomObject]$row
    }

    Write-Host "$rowCount sample rows generated successfully." -ForegroundColor Green
}

function Get-SampleValue($columnName, $rowNumber) {
    switch -Regex ($columnName.ToLower()) {
        "id|number" { return $rowNumber }
        "name" { return "Name$rowNumber" }
        "date" { return (Get-Date).AddDays($rowNumber).ToString("yyyy-MM-dd") }
        "email" { return "user$rowNumber@example.com" }
        "phone" { return "555-0$rowNumber" }
        "address" { return "$rowNumber Main St" }
        "city" { return "City$rowNumber" }
        "country" { return "Country$rowNumber" }
        "amount|price" { return [math]::Round((Get-Random -Minimum 10 -Maximum 1000), 2) }
        default { return "Value$rowNumber" }
    }
}

function Export-CSVToFile {
    if ($script:csvData.Count -eq 0) {
        Write-Host "No data to export. Please add some rows first." -ForegroundColor Yellow
        return
    }

    try {
        $script:csvData | Export-Csv -Path $script:csvFilePath -NoTypeInformation
        Write-Host "CSV exported successfully to: $script:csvFilePath" -ForegroundColor Green
    }
    catch {
        Write-Host "Error exporting CSV: $_" -ForegroundColor Red
    }
}

# Main program loop
do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-7)"

    switch ($choice) {
        "1" { Define-Columns }
        "2" { Add-Row }
        "3" { View-CurrentCSV }
        "4" { Import-FromJSON }
        "5" { Generate-SampleData }
        "6" { Export-CSVToFile }
        "7" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "7") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "7")

This CSV Generator Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to interactively build CSV structures:
    • Define columns
    • Add rows manually
    • View the current CSV structure
    • Import data from JSON
    • Generate sample data
    • Export the CSV to a file

Key features:

  1. Column Definition:
    • Allows users to define custom column names
  2. Manual Data Entry:
    • Supports adding rows manually with guided input for each column
  3. Data Visualization:
    • Provides a view of the current CSV structure in a tabular format
  4. JSON Import:
    • Allows importing data from a JSON file to quickly populate the CSV
  5. Sample Data Generation:
    • Automatically generates sample data based on column names
    • Supports common data types like IDs, names, dates, emails, etc.
  6. CSV Export:
    • Exports the generated data to a CSV file

This tool is particularly useful for:

  • Developers needing to create test data in CSV format
  • Data analysts creating sample datasets
  • QA engineers generating CSV files for testing
  • Anyone needing to quickly create structured CSV data

To use this script effectively:

  1. Run the script in PowerShell
  2. Use the menu options to build your CSV structure:
    • Start by defining columns
    • Add rows manually, import from JSON, or generate sample data
    • View the current structure at any time
  3. When finished, export the CSV to a file

This script provides a user-friendly way to create CSV structures without having to manually write CSV syntax or use spreadsheet software. It’s especially helpful for creating test data or sample datasets quickly and easily.

Streamlining Your Move to the Cloud: PowerShell Script for Mailbox Migration to Microsoft 365

As organizations transition to cloud-based solutions, migrating mailboxes to Microsoft 365 (formerly Office 365) is a common task. While the process can be complex, PowerShell provides powerful tools to automate and simplify this migration. In this post, we’ll explore a script that helps you migrate on-premises Exchange mailboxes to Microsoft 365.

The Problem: Manually migrating multiple mailboxes to Microsoft 365 is time-consuming and prone to errors.

The Solution: A PowerShell script that automates the process of creating migration batches and initiating the migration to Microsoft 365.

Here’s the script:

# Import required modules
Import-Module ExchangeOnlineManagement

# Connect to Exchange Online
Connect-ExchangeOnline

# Define variables
$CSVFile = "C:\Scripts\MailboxesToMigrate.csv"
$OnPremisesCredential = Get-Credential -Message "Enter on-premises Exchange admin credentials"
$TargetDeliveryDomain = "contoso.mail.onmicrosoft.com"  # Replace with your Microsoft 365 domain
$EndpointName = "OnPremEndpoint"  # Name for the migration endpoint

# Import list of mailboxes to migrate
$Mailboxes = Import-Csv $CSVFile

# Create a migration endpoint (if it doesn't exist)
if (!(Get-MigrationEndpoint -Identity $EndpointName -ErrorAction SilentlyContinue)) {
    New-MigrationEndpoint -ExchangeRemote -Name $EndpointName -Autodiscover -EmailAddress $OnPremisesCredential.UserName -Credentials $OnPremisesCredential
}

# Create a migration batch for each department
$Departments = $Mailboxes | Select-Object -ExpandProperty Department -Unique

foreach ($Dept in $Departments) {
    $BatchName = "Migrate-$Dept-$(Get-Date -Format 'yyyyMMdd')"
    $DeptMailboxes = $Mailboxes | Where-Object { $_.Department -eq $Dept }

    $MigrationBatch = New-MigrationBatch -Name $BatchName -SourceEndpoint $EndpointName -TargetDeliveryDomain $TargetDeliveryDomain
    
    foreach ($Mailbox in $DeptMailboxes) {
        $MoveRequest = New-MoveRequest -Identity $Mailbox.EmailAddress -Remote -RemoteHostName $TargetDeliveryDomain -TargetDeliveryDomain $TargetDeliveryDomain -RemoteCredential $OnPremisesCredential -BatchName $BatchName
    }

    # Start the migration batch
    Start-MigrationBatch -Identity $BatchName
    
    Write-Host "Migration batch $BatchName created and started for department: $Dept"
}

Write-Host "Migration batches created and started for all departments."

# Disconnect from Exchange Online
Disconnect-ExchangeOnline -Confirm:$false

How it works:

  1. The script connects to Exchange Online using the ExchangeOnlineManagement module.
  2. It reads a list of mailboxes to migrate from a CSV file.
  3. A migration endpoint is created if it doesn’t already exist.
  4. The script creates migration batches for each department.
  5. For each mailbox in a department, it creates a move request.
  6. Each migration batch is then started.

To use this script:

  1. Ensure you have the ExchangeOnlineManagement module installed (Install-Module ExchangeOnlineManagement).
  2. Prepare a CSV file (MailboxesToMigrate.csv) with columns: EmailAddress, Department.
  3. Modify the $CSVFile variable to point to your CSV file.
  4. Update the $TargetDeliveryDomain variable with your Microsoft 365 domain.
  5. Run the script in PowerShell with appropriate permissions.

Example CSV content:

CopyEmailAddress,Department
john.doe@contoso.com,Sales
jane.smith@contoso.com,Marketing
mike.johnson@contoso.com,IT
sarah.brown@contoso.com,Sales

Important considerations:

  1. Permissions: Ensure you have the necessary permissions both in your on-premises Exchange environment and in Microsoft 365 to perform migrations.
  2. Network bandwidth: Large-scale migrations can consume significant bandwidth. Plan your migration during off-peak hours if possible.
  3. Testing: Always test the migration process with a small batch of mailboxes before proceeding with a full-scale migration.
  4. User communication: Inform users about the migration process, potential downtime, and any actions they need to take.
  5. Verification: After migration, verify that all mailboxes have been moved successfully and that users can access their data.
  6. Cleanup: Once the migration is complete and verified, you may need to decommission the on-premises mailboxes and update DNS records.

Customizing the script:

  • You can modify the script to include additional parameters in the New-MoveRequest cmdlet, such as BadItemLimit or LargeItemLimit, to handle problematic items during migration.
  • Add error handling and logging to capture any issues that occur during the migration process.
  • Implement a progress bar or more detailed status updates for larger migrations.

Post-migration steps: After running this script and completing the migration, you should:

  1. Monitor the migration batches using the Get-MigrationBatch cmdlet.
  2. Check for any errors or warnings in the migration logs.
  3. Verify that all expected content has been migrated for a sample of users.
  4. Update user guides or documentation to reflect the new Microsoft 365 environment.
  5. Consider implementing additional Microsoft 365 features now that mailboxes are in the cloud.

Migrating mailboxes to Microsoft 365 can be a complex process, but PowerShell scripting can significantly streamline the operation. This script provides a solid foundation for automating your migration, allowing you to move mailboxes efficiently and in an organized manner.

Remember that while this script automates much of the process, it’s crucial to thoroughly plan your migration, prepare your environment, and test thoroughly before executing a large-scale move. Each organization’s needs may vary, so don’t hesitate to adapt this script to your specific requirements.

By leveraging PowerShell for your Microsoft 365 migration, you can ensure a more controlled, efficient, and error-free transition to the cloud. Happy migrating!

Streamlining User Management with PowerShell: Bulk User Creation Script

In today’s fast-paced IT environments, efficiently managing user accounts is crucial. Whether you’re setting up a new department or onboarding a group of employees, creating multiple user accounts can be time-consuming. This is where PowerShell comes to the rescue! In this post, we’ll explore a script that automates the process of creating multiple Active Directory users from a CSV file.

The Problem: You need to create numerous user accounts in Active Directory, each with specific attributes, and doing this manually is error-prone and time-consuming.

The Solution: A PowerShell script that reads user information from a CSV file and creates corresponding Active Directory accounts.

Here’s the script:

# Import the Active Directory module
Import-Module ActiveDirectory

# Specify the path to your CSV file
$csvPath = "C:\Scripts\NewUsers.csv"

# Import the CSV file
$users = Import-Csv -Path $csvPath

# Loop through each user in the CSV
foreach ($user in $users) {
    # Generate a username (first initial + last name)
    $username = ($user.FirstName.Substring(0,1) + $user.LastName).ToLower()
    
    # Generate an email address
    $email = "$username@yourdomain.com"
    
    # Create a secure password
    $securePassword = ConvertTo-SecureString $user.Password -AsPlainText -Force
    
    # Specify the OU where the user account will be created
    $ou = "OU=NewUsers,DC=yourdomain,DC=com"
    
    # Create the new user account
    New-ADUser -Name "$($user.FirstName) $($user.LastName)" `
               -GivenName $user.FirstName `
               -Surname $user.LastName `
               -SamAccountName $username `
               -UserPrincipalName $email `
               -Path $ou `
               -AccountPassword $securePassword `
               -ChangePasswordAtLogon $true `
               -Enabled $true `
               -EmailAddress $email `
               -Title $user.JobTitle `
               -Department $user.Department
    
    Write-Host "Created user account for $($user.FirstName) $($user.LastName)"
}

Write-Host "User creation process complete!"

How it works:

  1. The script imports the Active Directory module.
  2. It reads user information from a specified CSV file.
  3. For each user in the CSV, it:
    • Generates a username and email address.
    • Creates a secure password object.
    • Creates a new AD user with specified attributes.
  4. It provides feedback for each created user.

To use this script:

  1. Prepare a CSV file (NewUsers.csv) with columns: FirstName, LastName, Password, JobTitle, Department.
  2. Modify the $csvPath variable to point to your CSV file.
  3. Adjust the $ou variable to specify the correct Organizational Unit.
  4. Update the email domain in the $email variable.
  5. Run the script in PowerShell with appropriate permissions.

Example CSV content:

CopyFirstName,LastName,Password,JobTitle,Department
John,Doe,P@ssw0rd123!,Manager,Sales
Jane,Smith,Str0ngP@ss!,Developer,IT

Important considerations:

  • Ensure you have the necessary permissions to create AD users.
  • Be cautious with password handling; consider using a more secure method in production environments.
  • Always test scripts in a non-production environment first.
  • Comply with your organization’s security policies and password requirements.

This script can save hours of manual work when onboarding multiple users. You can easily extend it to include additional attributes or perform extra actions like adding users to specific groups.

PowerShell’s ability to interact with Active Directory makes it an invaluable tool for IT administrators. By automating repetitive tasks like user creation, you can focus on more strategic aspects of your role.

Remember, with great power comes great responsibility. Always double-check your CSV data and script logic before running bulk operations in your Active Directory environment.