0

I am writing a script to read a Status file to record the status of a device. The file follows this style of 'rules': The first line is "[ACTIVE_JOB]" followed by the Jobs listed on each line. Then, there is a line that says "[COMPLETE_JOB]" followed by the jobs listed on each line that are done. At the end of that list, it goes into some other stuff I don't care about, but the first line of the 'other stuff' always starts with a "[". So here's the deal, when I shove the stuff into an Array, and then do a split on the array, if there are NO Active Jobs, it seems to shove the first Completed Job into the Active Jobs array. I'm just trying to make a list or array of the Active Jobs and the Completed Jobs, but alas it is tripping me up when there are no Active Jobs.

Anyways, here is the snippit I am working on (You can uncomment the PATH variable sets to alternate between testing the file reading, if that makes things easier):

#$Path = 'C:\Scripts\NoJOBS.txt'
#$Path = 'C:\Scripts\NoActiveJobs.txt'
#$Path = 'C:\Scripts\ManyJobs.txt'
$StatusFile = Get-Content $path ##  Reads the Status File as an array
#$StatusArray = @()
#$ActiveJobs = @()
#$CompleteJobs = @()
$StatusArray = New-Object System.Collections.ArrayList
$ActiveJobs = New-Object System.Collections.ArrayList
$CompleteJobs = New-Object System.Collections.ArrayList

foreach ($Line in $StatusFile) {
if ($Line -like "*PUBLISHER*") {Break}
#$StatusArray += $Line
$StatusArray.Add($Line)
}
$Seperator = "[ACTIVE_JOB]","[COMPLETE_JOB]"
$ActiveJobs,$CompleteJobs = $StatusArray.Split($Seperator,2,[System.StringSplitOptions]::RemoveEmptyEntries)
#$ActiveJobs = [System.Collections.ArrayList]$ActiveJobs
#$CompleteJobs = [System.Collections.ArrayList]$CompleteJobs
foreach ($Job in $ActiveJobs) {
    #if($job.Contains("[")){ $ActiveJobs.Remove($Job) }
    if($job.Contains("[")){ $ActiveJobs = $ActiveJobs | ? {$_ -ne $job} }

}
foreach ($Job in $CompleteJobs) {
    #if($job.Contains("[")){ $CompleteJobs.Remove($Job) }
    if($job.Contains("[")){ $CompleteJobs = $CompleteJobs | ? {$_ -ne $Job } }

}

And here is what the file reads like if there are no jobs (Save as NoJOBS.txt):

[ACTIVE_JOB]
[COMPLETE_JOB]
[PUBLISHER1]
NAME=PP-50 1
STACKER1=62
STACKER2=9
STACKER3=0

Here is what it reads like if there is 1 Completed Jobs, but no Active Jobs (Save as NoActiveJobs.txt):

[ACTIVE_JOB]
[COMPLETE_JOB]
JOB1=Frank_L_Smith-085149-08092017
[Frank_L_Smith-085149-08092017]
STATUS=99

And finally, here is what it looks like with 1 active job, and many completed jobs (Save as ManyJobs.txt):

[ACTIVE_JOB]
JOB1=April_Ztest-124856-31082017
[COMPLETE_JOB]
JOB1=Mel_R_Smith-141307-31082017
JOB2=Mel_R_Smithe-132029-31082017
JOB3=Melvin_R_Smithy-131037-31082017
JOB5=Will_R_Smith-123534-31082017
[Mel_R_Smith-141307-31082017]
PUBLISHER=PP-50 1
STATUS=4
PUBLICATION_NUMBER=1
COMPLETION_NUMBER=1
ERRORDISC_NUMBER=0

Using PSVersion 5.1.14393.1066 on Win10 with .NET 4.7

  • Looks like you are trying to parse an file with ini syntax. Why not use an existing ini parser like [PSIni](https://github.com/lipkau/PsIni)? – BenH Sep 08 '17 at 19:16
  • @BenH Hmm, I'm trying to use no add-ons but I could try it... Thank you for that suggestion!! At some point my script will be one several production computers so I wanted to make setup as easy breezy as possible, but if it works it works!! – Drew Courtney Sep 08 '17 at 19:31
  • `Get-IniContent` would be all you would need to include and that's ~80 lines. But there are plenty of other solutions out there like this [SO question](https://stackoverflow.com/questions/417798/ini-file-parsing-in-powershell). – BenH Sep 08 '17 at 19:38
  • I was able to find the ScriptingGuys post about this, and included enough of his snippet to make something slick!! Just change the INI extension requirement to txt and it works super slick! Please provide your comment as an answer and i will declare it the answer! Thank you @BenH!!! – Drew Courtney Sep 08 '17 at 19:41

1 Answers1

0

Added this function from TheScritpingGuy and it works like a charm!! Thank you @BenH !!

Function Get-IniContent {  
    <#  
    .Synopsis  
        Gets the content of an INI file  

    .Description  
        Gets the content of an INI file and returns it as a hashtable  

    .Notes  
        Author        : Oliver Lipkau <oliver@lipkau.net>  
        Blog        : http://oliver.lipkau.net/blog/  
        Source        : https://github.com/lipkau/PsIni 
                      http://gallery.technet.microsoft.com/scriptcenter/ea40c1ef-c856-434b-b8fb-ebd7a76e8d91 
        Version        : 1.0 - 2010/03/12 - Initial release  
                      1.1 - 2014/12/11 - Typo (Thx SLDR) 
                                         Typo (Thx Dave Stiff) 

        #Requires -Version 2.0  

    .Inputs  
        System.String  

    .Outputs  
        System.Collections.Hashtable  

    .Parameter FilePath  
        Specifies the path to the input file.  

    .Example  
        $FileContent = Get-IniContent "C:\myinifile.ini"  
        -----------  
        Description  
        Saves the content of the c:\myinifile.ini in a hashtable called $FileContent  

    .Example  
        $inifilepath | $FileContent = Get-IniContent  
        -----------  
        Description  
        Gets the content of the ini file passed through the pipe into a hashtable called $FileContent  

    .Example  
        C:\PS>$FileContent = Get-IniContent "c:\settings.ini"  
        C:\PS>$FileContent["Section"]["Key"]  
        -----------  
        Description  
        Returns the key "Key" of the section "Section" from the C:\settings.ini file  

    .Link  
        Out-IniFile  
    #>  

    [CmdletBinding()]  
    Param(  
        [ValidateNotNullOrEmpty()]  
        [ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".txt")})]  
        [Parameter(ValueFromPipeline=$True,Mandatory=$True)]  
        [string]$FilePath  
    )  

    Begin  
        {Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started"}  

    Process  
    {  
        Write-Verbose "$($MyInvocation.MyCommand.Name):: Processing file: $Filepath"  

        $ini = @{}  
        switch -regex -file $FilePath  
        {  
            "^\[(.+)\]$" # Section  
            {  
                $section = $matches[1]  
                $ini[$section] = @{}  
                $CommentCount = 0  
            }  
            "^(;.*)$" # Comment  
            {  
                if (!($section))  
                {  
                    $section = "No-Section"  
                    $ini[$section] = @{}  
                }  
                $value = $matches[1]  
                $CommentCount = $CommentCount + 1  
                $name = "Comment" + $CommentCount  
                $ini[$section][$name] = $value  
            }   
            "(.+?)\s*=\s*(.*)" # Key  
            {  
                if (!($section))  
                {  
                    $section = "No-Section"  
                    $ini[$section] = @{}  
                }  
                $name,$value = $matches[1..2]  
                $ini[$section][$name] = $value  
            }  
        }  
        Write-Verbose "$($MyInvocation.MyCommand.Name):: Finished Processing file: $FilePath"  
        Return $ini  
    }  

    End  
        {Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended"}  
}