DarkLite1
DarkLite1

Reputation: 14695

Creating objects from text file

We have the following text file:

[UserA]
;Path1 in comment
Path 2
Path 3

[UserB]
Path 1
[UserC]
Path 1
Path 2

We're trying to create one object per user with the properties SamAccountName and Path. The following code does this but it's not able to catch the last object:

Param (
    [String]$File = 'S:\Test\Brecht\Input_Test\files.ini'
)

#<# TEST
    $VerbosePreference = 'Continue'
#>

$Hash = @{}
$Path = @()

$FileContent = Get-Content $File | where {$_ -notlike ';*'} 

$Objects = $FileContent | ForEach-Object {
    Write-Verbose "Text line '$_'"

    if ($_ -match '\[') {
        if ($Path.Length -ne 0) {
            $Hash.Path = $Path
            New-Object –TypeName PSObject -Property $Hash
        }

        $Hash = @{}
        $Path = @()
        $Hash.SamAccountName = $_.Split('[,]')[1]
    }
    else {
        Write-Verbose "Add path '$_'"
        $Path += [PSCustomObject]@{
            Original = $_
            Test     = $null
        }
    }    
}

Is there a better way to do this?

Upvotes: 1

Views: 2482

Answers (2)

DarkLite1
DarkLite1

Reputation: 14695

Ultimately I chose to do it with a for loop. It gives me more control:

$FileContent = (Get-Content $File | where {($_ -notlike ';*') -and $_}) -split '\['

$Objects = for ($i=0; $i -lt $FileContent.Length; $i++) {
    if ($FileContent[$i] -eq '') {
        $SpaceIndex = $i
        Write-Verbose "Initiate object"
        $Object = [PSCustomObject]@{
            SamAccountName = $null
            Path           = @()
        }
    }
    if ($FileContent[$i -1] -eq '') {
        Write-Verbose "SamAccountName '$($FileContent[$i])'"
        $Object.SamAccountName = $FileContent[$i].TrimEnd(']')
    }
    if (($i -ne $SpaceIndex) -and ($i -ne $SpaceIndex +1)) {
        Write-Verbose "Path '$($FileContent[$i])'"
        $Object.Path += [PSCustomObject]@{
            Original = $FileContent[$i]
            Test     = $null
        }  
    }
    if (($FileContent[$i+1] -eq '') -or ($i -eq $FileContent.Length -1)) {
        Write-Verbose "Create object"
        $Object
    }
}

Upvotes: 1

Martin Brandl
Martin Brandl

Reputation: 58931

For a fast solution, you could use the -End parameter from the Foreach-Object cmdlet:

$Objects = $FileContent | ForEach-Object {
    Write-Verbose "Text line '$_'"

    if ($_ -match '\[') {
        if ($Path.Length -ne 0) {
            $Hash.Path = $Path
            New-Object –TypeName PSObject -Property $Hash
        }

        $Hash = @{}
        $Path = @()
        $Hash.SamAccountName = $_.Split('[,]')[1]
    }
    else {
        Write-Verbose "Add path '$_'"
        $Path += [PSCustomObject]@{
            Original = $_
            Test     = $null
        }
    }    
} -End {
 if ($Path.Length -ne 0) {
            $Hash.Path = $Path
            New-Object –TypeName PSObject -Property $Hash
        }
}

Upvotes: 1

Related Questions