I have INI file and I want to get specific section. The items in the section that I choose are 24 items. I want to use all the item to write in a file. I tried this, It works, but it looks like bad way to write 24 times to do the process. Is there any other way to do that more beautiful? The section of my INI file like this
Input ini:
[Code]
A1=12,34,56
A2=23,45,67
A3=34,56,78,9,10
...
A24=a1,b2,c3,d4,e5
Script:
Function F_ML
{
$FilePath = "C:\Users\File.ini"
$section = "Code"
$R_1 = "A1"
$R_2 = "A2"
$R_3 = "A3"
$R_4 = "A4"
$R_5 = "A5"
$R_6 = "A6"
$R_7 = "A7"
$R_8 = "A8"
$R_9 = "A9"
$R_10 = "A10"
$R_11 = "A11"
$R_12 = "A12"
$R_13 = "A13"
$R_14 = "A14"
$R_15 = "A15"
$R_16 = "A16"
$R_17 = "A17"
$R_18 = "A18"
$R_19 = "A19"
$R_20 = "A20"
$R_21 = "A21"
$R_22 = "A22"
$R_23 = "A23"
$R_24 = "A24"
$store = "C:\Users\"
$FilePath
$input_file = $FilePath
$ini_file = #{}
Get-Content $input_file | ForEach-Object {
$_.Trim()
} | Where-Object {
$_ -notmatch '^(;|$)'
} | ForEach-Object {
if ($_ -match '^\[.*\]$') {
$section = $_ -replace '\[|\]'
$ini_file[$section] = #{}
} else {
$key, $value = $_ -split '\s*=\s*', 2
$ini_file[$section][$key] = $value
}
}
#--------
$Path_Store = $store
#---------
$Get_1 = $ini_file.($section).($R_1)
$L_1 = $Get_1.Substring(0,3)
$Get_2 = $ini_file.($section).($R_2)
$L_2 = $Get_2.Substring(0,3)
$Get_3 = $ini_file.($section).($R_3)
$L_3 = $Get_3.Substring(0,3)
#---------
$Outer = ";********************"
$Header = ";*******************"
$ML = "12345"
$FB = ";Initial=1a2b"
#----------
$B_ID_1 = ";Build=" + $ML + "#" + "S" + $L_1 + "#" + "D" + $L_1
$CRM_1 = ";CRM=" + $R_1
$Output_1 = $Header, $B_ID_1, $FB, $CRM_1 , $Outer | Out-File $Path_Store\A1
$B_ID_2 = ";Build=" + $ML + "#" + "S" + $L_2 + "#" + "D" + $L_2
$CRM_2 = ";CRM=" + $R_2
$Output_2 = $Header, $B_ID_2, $FB, $CRM_2 , $Outer | Out-File $Path_Store\A2
$B_ID_3 = ";Build=" + $ML + "#" + "S" + $L_3 + "#" + "D" + $L_3
$CRM_3 = ";CRM=" + $R_3
$Output_3 = $Header, $B_ID_3, $FB, $CRM_3 , $Outer | Out-File $Path_Store\A3
#---------
}
$call = F_ML
My expectation, I can make this way shorter and the output is getting 24 output file.
Output Sample
Output File 1
;********************
;Build=12345#S12#D12
;Initial=1a2b
;CRM=A1
;********************
Output File 2
;********************
;Build=12345#S23#D23
;Initial=1a2b
;CRM=A2
;********************
Try below...
$IniContent = Get-Content -Path $IninPath
$IniContent | ForEach-Object -Process {
$Split = $_ -split '=';
$OutPutfilePath = "c:\temp\$($Split[0]).txt"
$first = ($Split[1] -split ',')[0]
$append = "#S{0}D{1}" -f $first,$first
# create a herestring to build the output
#"
;********************
;Build=$Ml$append
$FB
;CRM=$($Split[0])
;********************
"# | Out-File -Path $OutPutfilePath -Force
}
Use a ForEach to manipulate a string and Invoke the Expression.
1..24 | ForEach-Object { Invoke-Expression -Command (
'$R_{0} = "A{0}"' -f $_
)}
.
.
.
1..24 | ForEach-Object { Invoke-Expression -Command (
'$Get_{0} = $ini_file.($section).($R_{0}) `
$L_{0} = $Get_{0}.Substring(0,3)' -f $_
)}
.
.
.
1..24 | ForEach-Object { Invoke-Expression -Command (
'$B_ID_{0} = ";Build=" + $ML + "#" + "S" + $L_{0} + "#" + "D" + $L_{0}
$CRM_{0} = ";CRM=" + $R_{0}
$Output_{0} = $Header, $B_ID_{0}, $FB, $CRM_{0} , $Outer | Out-File $Path_Store\A{0}' -f $_
)}
{0} will be replaced by the value behind -f so it will be replaced Foreach number from 1 to 24...
Would this work?
All I did here was use your existing code to run everything in a loop from 1 to 24, removing the duplicated code. I reformatted it a little so it was a little easier for me to read.
Essentially, the variable $i will be a number from 1 to 24, while the variable $R will be "A" and whatever number is in $i (essentially A + $i)
Function F_ML
{
$section = "Code"
$store = "C:\Users\"
$input_file = "C:\Users\File.ini"
$ini_file = #{}
for ($i=1; $i -le 24; $i++)
{
$R = "A$($i)"
Get-Content $input_file |
ForEach-Object `
{
$_.Trim()
} |
Where-Object `
{
$_ -notmatch '^(;|$)'
} |
ForEach-Object `
{
if ($_ -match '^\[.*\]$')
{
$section = $_ -replace '\[|\]'
$ini_file[$section] = #{}
}
else
{
$key, $value = $_ -split '\s*=\s*', 2
$ini_file[$section][$key] = $value
}
}
#--------
$Path_Store = $store
#---------
$Get = $ini_file.($section).($R)
$L = $Get.Substring(0,3)
#---------
$Outer = ";********************"
$Header = ";*******************"
$ML = "12345"
$FB = ";Initial=1a2b"
#----------
$B_ID = ";Build=" + $ML + "#" + "S" + $L + "#" + "D" + $L
$CRM = ";CRM=" + $R
$Output = $Header, $B_ID, $FB, $CRM , $Outer | Out-File $Path_Store\$R
}
}
Related
I have this script, it searches a Word document for "Detection Method Type", then pulls the value from the 5th line along, say "C:\program files\test\notepad.exe", the script should then split it to $filepath = C:\program files\test and $file = notepad.exe.
I get the following error when trying to pass the above to new-cmdetectionclausefile:
New-CMDetectionClauseFile : Cannot validate argument on parameter 'FileName'. System.Management.Automation.ValidationMetadataException
At line:8 char:70
+ ... new-CMdetectionClauseFile -path $filepathexe -filename $file -Existe ...
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [New-CMDetectionClauseFile], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ConfigurationManagement.PowerShell.Cmdlets.Dcm.NewDetectionClauseFile*
ERROR:
the problem happens with the $file even though it's populated
pre-requisites:
myscript
configurationmanager.ps1
docx that contains: Detection Method Type C:\program files\test\notepad.exe
script:
param($documentPath)
function get-documentclause{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][string]$documentPath
)
$documentPath = "D:\Documents\Packaging Scripts\test.docx"
<#
cells have an end-of-0cell marker of two chars (bytes 13 and 7)
we will need to trim these later
convert bytes to char and join as string
#>
$endOfCellMarker = -join #([char][byte]13, [char][byte]7)
# instantiate Word Com Object
$wordApplication = New-Object -ComObject Word.Application
<#
open the document:
param 1 = FileName
param 2 = ConfirmConversions
param 3 = ReadOnly$doclause
(param 2 only needed because this method accepts only positional parameters)
see https://learn.microsoft.com/en-us/office/vba/api/word.documents.open
#>
$wordDocument = $wordApplication.Documents.Open($documentPath, $false, $true)
$doclause = ""
$regclause = ""
$fileclause = ""
try{
#check to see if document is a table or paragraph
$count = 0
foreach($tables in $wordDocument.Tables){
$count++
}
#if document is true (paragraph) else it will be treated as table
if($count -eq 1){
$count = 0
foreach($para in $wordDocument.Paragraphs){
#Write-Host $para.range.text
#Write-Host "$count"
#$wordtolookfor = $para.Range(3).Text
$word = $para.Range.text
#$word
#pause
if ($word -like "*Detection Method Type*"){
$num = $count + 5
#Write-Host $wordDocument.Paragraphs($num).range.text
$doclause = $wordDocument.Paragraphs($num).range.text
} #end of if
$count++
}#end of foreach
} else {$doclause = $wordDocument.Tables.Item(8).cell(4,2).range.text}
}catch{}
#test if the clause makes sense
$doclause = $doclause.ToString().Trim()
#test if detection method contains exe or registry path
if(($doclause -like "*.exe*") -xor ($doclause -like "*CurrentVersion\Uninstall*")){
if($doclause -like "*.exe*") {
[string]$filepathexe = split-path -parent $doclause
[string]$file = $doclause.Split("\") | Select-Object -last 1
$fileclause = new-CMdetectionClauseFile -path $filepathexe -filename $file -Existence
} #end of exe clause
#if file does contain reg run the following
elseif($doclause -like "*CurrentVersion\Uninstall*") {
#selects the first backslash
$hive = $doclause.Split("\") | Select-Object -First 1
#replaces the underscore withnothing
$hive = $hive.Replace("_","")
#removes the first 4 characters HKEY
$hive = $hive.substring(4)
#produce the rest of the key
$path = $doclause.Split("\") | Select-Object -last 7
$path = $path -join "\"
$path = Split-Path $path -Parent
#get final value
$regvalue = Split-Path -Leaf $doclause
$regclause = New-CMDetectionClauseRegistryKeyValue -Hive $hive -KeyName $path -PropertyType String -ValueName $regvalue -Existence
} #end of reg clause
else {
$regclause = ""
$fileclause = ""
}
} #end of testing clause
else {$doclause = ""}
$nothing = ""
# close the file and do not save changes
$wordDocument.Close([ref] [Microsoft.Office.Interop.Word.WdSaveOptions]::wdDoNotSaveChanges)
# end the WINWORD.EXE process
$wordApplication.Quit()
if($regclause){
return $regclause
#return #($hive,$path,$regvalue) this works but testing if previous would have worked too
}
elseif($fileclause){return $fileclause}
else {
Return $nothing
$regclause = ""
$fileclause = ""
}
}
answer found
before
$fileclause = new-CMdetectionClauseFile -path $filepathexe -filename $file -Existence
add:
$asd = [string]$file -replace"\u007",""
$asd2 = [string]$asd -replace"t|n|r",""`
then change
$fileclause = new-CMdetectionClauseFile -path $filepathexe -filename $asd2 -Existence
exporting $file to a text file you get the expect result plus a "[]" symbol, loading that in to notepad++ it can be resolved to 0007 which is Unicode for a bell symbol, remove that and what not.
I read a lot of questions here about this and i don't find what i search ...
I start scripting with powershell (just for information :p )
I want to modify a CSV file, exported from a database with information like "FirstName,LastName,OtherMail,IDAurion,Department". I have to add some titles to the HEADER, and i have to take informations in the CSV to concatenate some informations and put them in another CSV file.
I don't know if i explain well, i put you my script :
$OriginalCSV = "$PSScriptRoot\original.csv"
function Remove-StringLatinCharacters
{
PARAM ([string]$String)
[Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($String))
}
Import-Csv -path $OriginalCSV -Encoding Default | ForEach-Object {
$OtherMail = $_.OtherMail
$IDAurion = $_.IDAurion
$Department = $_.Department
$FirstnameCSV = $_.FirstName
$FirstName = $FirstnameCSV -replace '(^\s+|\s+$)',''
$FirstnameNoLatin = Remove-StringLatinCharacters $FirstName
$FirstnameNoLatinNoSpace = $FirstnameNoLatin -replace '\s','-'
$FirstnameFirstLetterUpper = $Firstname.Substring(0,1).ToUpper()
$LastNameCSV = $_.LastName
$LastName = $LastnameCSV -replace '(^\s+|\s+$)',''
$LastnameNoLatin = Remove-StringLatinCharacters $LastName
$LastnameNoLatinNoSpace = $LastnameNoLatin -replace '\s',''
$LastnameFirstLetterUpper = $Lastname.Substring(0,1).ToUpper()
$UserPrincipalNameCSV = $FirstnameCSV + "." + $LastNameCSV + "#campus.ocellia.fr"
$UserPrincipalNameConcatene = $FirstnameNoLatinNoSpace + "." + $LastNameNoLatinNoSpace + "#email.fr"
$UserPrincipalName = $UserPrincipalNameConcatene.ToLower()
$MailNickName = $FirstnameNoLatinNoSpace.substring(0,1).toupper() + $($FirstnameNoLatin.substring(1).tolower() -replace '\s','') + $LastnameNoLatinNoSpace.toupper()
$Password = $FirstnameFirstLetterUpper + $LastnameFirstLetterUpper + $IDAurion + "$"
$Number = 0
Get-Content $OriginalCSV |
ForEach-Object{
If($Number -eq 0){
$_ + ",MailNickName" + ",Password" + ",UserPrincipalName"
$Number = 1
}
Else {
$_ + "," + $MailNickName + "," + $Password + "," + $UserPrincipalName
}
} | Out-File $PSScriptRoot\Modified-CSV.csv
}
This work for 1 line, but not for multiples line ...
Edit :
This is the examples for input CSV and how i want the resulting output CSV:
Input csv :
Firstname,Lastname,OtherMail,ID,Department
Pierre,DUPONT,pierre.dupont#mail.com,123456,Paris
Marie,CHANTAL,marie.chantal#mail.com,456789,Marseille
Output csv:
Firstname,Lastname,OtherMail,ID,Department,MailNickName,Password,UserPrincipalName
Pierre,DUPONT,pierre.dupont#mail.com,123456,Paris,PierreDupont,PD123456,p.dupont#entreprise.com
Marie,CHANTAL,marie.chantal#mail.com,456789,Marseille,MarieCHANTAL,MC456789,m.chantal#entreprise.com
I'm guessing this is what you're trying to do but since we don't have a minimal reproducible example it's quite hard to tell. I also attempted to improve your code, there was a lot of redundancy.
$OriginalCSV = "$PSScriptRoot\original.csv"
$ModifiedCSV = "$PSScriptRoot\modified.csv"
$txtInfo = (Get-Culture).TextInfo
function Remove-StringLatinCharacters
{
PARAM ([string]$String)
[Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($String))
}
(Import-Csv -Path $OriginalCSV -Encoding Default | ForEach-Object {
$OtherMail = $_.OtherMail.Trim()
$IDAurion = $_.IDAurion.Trim()
$Department = $_.Department.Trim()
$FirstnameCSV = $_.FirstName.Trim()
$LastNameCSV = $_.LastName.Trim()
$firstName = (Remove-StringLatinCharacters $FirstName) -replace '\s','-'
$lastName = (Remove-StringLatinCharacters $LastName) -replace '\s'
$UserPrincipalName = "$FirstnameCSV.$LastNameCSV#campus.ocellia.fr"
$UserPrincipalNameConcat = "$firstName.$lastName#email.fr".ToLower()
$MailNickName = $txtInfo.ToTitleCase($firstName) + $lastName.ToUpper()
$Password = "{0}{1}$IDAurion$" -f $firstName.ToUpper()[0],$lastName.ToUpper()[0]
[pscustomobject]#{
FirstNameCSV = $FirstnameCSV
LastNameCSV = $LastNameCSV
OtherMail = $OtherMail
IDAurion = $IDAurion
Department = $Department
MailNickName = $MailNickName
Password = $Password
UserPrincipalNameCAMPUS = $UserPrincipalName
UserPrincipalNameEMAILFR = $UserPrincipalNameConcat
}
} | ConvertTo-Csv -NoTypeInformation) -replace '"' |
Out-File $ModifiedCSV
I have a powershell script, I want that it'll always return the number with 2 decimal place (I.E 1 = 1.00, 1.1 = 1.10, 1.11 = 1.11)
I've managed to do it for 1 and 1.11, but I can think of a solution that wont take too much space for 1.1.
Thats what I got:
$Result = $shippingprice % 2
IF ($Result -ne 1 -and $Result -ne 0)
{
$shippingpricestring = "$" + $shippingprice.ToString()
}
else {
$shippingpricestring = "$" + ($shippingprice | % { '{0:0.00}' -f $_ })
}
$Result = $itemprice % 2
IF ($Result -ne 1 -and $Result -ne 0)
{
$itempricestring = "$" + $itemprice.ToString()
}
else {
$itempricestring = "$" + ($itemprice | % { '{0:0.00}' -f $_ })
}
IF ($Result -ne 1 -and $Result -ne 0)
{
$taxstring = "$" + $tax.ToString()
}
else {
$taxstring = "$" + ($tax | % { '{0:0.00}' -f $_ })
}
$Result = $finalrice % 2
IF ($Result -ne 1 -and $Result -ne 0)
{
$finalricestring = "$" +$finalrice.ToString()
}
else {
$finalricestring = "$" + ($finalrice | % { '{0:0.00}' -f $_ })
}
$shippingpricestring = "$" + $shippingprice.ToString("#.##")
Scripting Guy Reference: Hey Scripting Guy
$shippingprice = 17.1111
$ItemPrice = 4.1211
$tax = 94.919
$finalrice =10.3211
$Result = $shippingprice % 2
IF ($Result -ne 1 -and $Result -ne 0)
{
$shippingpricestring = "$" + $shippingprice.ToString("#.##")
}
else {
$shippingpricestring = "$" + ($shippingprice | % { '{0:0.00}' -f $_ })
}
Write-Output $shippingpricestring
IF ($Result -ne 1 -and $Result -ne 0)
{
$itempricestring = "$" + $itemprice.ToString("#.##")
}
else {
$itempricestring = "$" + ($itemprice | % { '{0:0.00}' -f $_ })
}
Write-Output $itempricestring
IF ($Result -ne 1 -and $Result -ne 0)
{
$taxstring = "$" + $tax.ToString("#.##")
}
else {
$taxstring = "$" + ($tax | % { '{0:0.00}' -f $_ })
}
Write-Output $taxstring
$Result = $finalrice % 2
IF ($Result -ne 1 -and $Result -ne 0)
{
$finalricestring = "$" +$finalrice.ToString("#.##")
}
else {
$finalricestring = "$" + ($finalrice | % { '{0:0.00}' -f $_ })
}
Write-Output $finalricestring
RESULT
$17.11
$4.12
$94.92
$10.32
*** The above assumes that all the variables have more than 2 decimal spaces. If say $tax = 9.9 $taxstring would appear as 9.9 and NOT as 9.90
If you want to format the number with .ToString you can go with .ToString(format)
Example
$list = 1, 1.1, 1.111, 1.1111
$list | %{$_.ToString("0.00")}
Output
1.00
1.10
1.11
1.11
I´m working on a code that is supposed to import-csv - change the content, and then export to csv.
I´ve tried to export with Export-Csv - but it only writes the lenght of the string
I also tried with StreamWriter - but it only writes $Resultat once
I am new to PowerShell :-)
$workfile = import-csv "X:\powershell\converter\test.csv" -Delimiter ';'
ForEach ($item in $workfile)
{
$Id = $item.("ID")
$Maaler = $item.("Maaler")
$Fra = $item.("Fra")
$Til = $item.("Til")
#Dato gymnastik
$Tilto = $item.("Til")
$Tilto = $Tilto.substring(0,10)
$Til = $Til.substring($Til.length - 8, 8)
$Forbrug = $item.("Forbrug")
$Enhed = $item.("Enhed")
$aflaesningstype = $item.("Aflæsningstype?")
$T = ".000+02:00"
$Resultat = $Tilto + "T" + $Til + $T + ',"' + $Maaler + '","' + '","' + '","' + '","' + '","' + $Forbrug + '","' + $Enhed + '","' + '255"'
Write-output "$Resultat"
}
$Resultat | Export-Csv "X:\powershell\behandlet\Output $(get-date -f dd-MM-yyyy-hh-mm-ss).csv" -Delimiter ',' -NoType
#$fhStream = [System.IO.StreamWriter] "X:\powershell\behandlet\Output $(get-date -f dd-MM-yyyy-HH-mm-ss).csv"
#$fhStream.WriteLine($Resultat)
#$fhStream.Close()
The Write-output shows the output in the right way
Can anyone see what I am doing wrong ?
Try this:
$workfile = import-csv "X:\powershell\converter\test.csv" -Delimiter ';'
$result = New-Object System.Collections.ArrayList
ForEach ($item in $workfile)
{
$Id = $item.("ID")
$Maaler = $item.("Maaler")
$Fra = $item.("Fra")
$Til = $item.("Til")
#Dato gymnastik
$Tilto = $item.("Til")
$Tilto = $Tilto.substring(0,10)
$Til = $Til.substring($Til.length - 8, 8)
$Forbrug = $item.("Forbrug")
$Enhed = $item.("Enhed")
$aflaesningstype = $item.("Aflæsningstype?")
$T = ".000+02:00"
$result += $Tilto + "T" + $Til + $T + ',"' + $Maaler + '","' + '","' + '","' + '","' + '","' + $Forbrug + '","' + $Enhed + '","' + '255"'
}
$result | Out-File "X:\powershell\behandlet\Output $(get-date -f dd-MM-yyyy-hh-mm-ss).csv"
EDITED:
Text1.txt:
123.456.789.189:12345
222.222.222.444:56789
451.200.111.321:55555
333.333.333.111:11223
I want to compare ID with IP that weren't registered.
ERROR:
Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: '123.456.789.189:12345' Key being added: '123.456.789.189:12345'" + $nameHash.Add( $data3[4], $data3[3] )
I think this error is due to the existence of duplicates.
How do I solve an issue with duplicates in Hash Table?
My function to calculate time takes in a startdate and an end date.
Function calTimeDiff( $StartDate, $EndDate )
{
"which is = " + (NEW-TIMESPAN –Start $StartDate –End $EndDate).Hours + " hours, " +
(NEW-TIMESPAN –Start $StartDate –End $EndDate).Minutes + " minutes, " +
(NEW-TIMESPAN –Start $StartDate –End $EndDate).Seconds + " seconds, " +
"diff = " + (NEW-TIMESPAN –Start $StartDate –End $EndDate).TotalSeconds + " sec"
}
$lines1 = Get-Content "C:\Temp\Text1.txt" | Select-Object -Unique
$lines2 = Get-Content "C:\Temp\Text2.txt" | Select-Object -Unique
ForEach( $line2 in $lines2 )
{
$list = ( $date, $time, $client, $clientIP )
$list = $line2.Split( "" )
ForEach( $line1 in $lines1 )
{
$disconnectIP = $line1
If( $disconnectIP -match $list[3] )
{
$date = $list[0]
$time = $list[1]
$client = $list[2]
$clientIP = $list[3]
If( $client -eq "serviceClient" )
{
$start = $date + " " + $time
}
If( $client -eq "Unregistered" )
{
$end = $date + " " + $time
}
calTimeDiff $start $end
}
}
}
How about something along these lines? I think it's basically behaving the way you were asking for (although you might want to tweak the display-span function a bit...)
#requires -Version 3
function parse-log
{
param(
[string]$line
)
$data = $line.split(' ')
$dateString = '{0} {1}' -f $data[0], $data[1]
$timeStamp = Get-Date -Date $dateString
[pscustomobject]#{
TimeStamp = $timeStamp
Client = $data[2]
IPAddress = $data[3]
}
}
function display-span
{
param(
$logSpan
)
'{0} ({1}) ==> {2}' -f $logSpan.IPAddress, $nameHash.Get_Item( $logSpan.IPAddress), $logSpan.Start
'{0} ({1}) ==> {2}' -f $logSpan.IPAddress, $nameHash.Get_Item( $logSpan.IPAddress), $logSpan.End
'Start = {0}, End = {1}, diff = {2}' -f $logSpan.Start, $logSpan.End, $logSpan.TimeSpan
''
}
$ipStateHash = #{}
$nameHash = #{}
$logArray = #()
$lines1 = Get-Content -Path '.\Text1.txt'
$lines2 = Get-Content -Path '.\Text2.txt'
$lines3 = Get-Content -Path '.\Text3.txt'
# Build Name Hash
foreach( $line3 in $lines3 )
{
$data3 = $line3.Split( ' ' )
$nameHash.Add( $data3[4], $data3[3] )
}
foreach( $line2 in $lines2 )
{
$entry = parse-log -line $line2
switch( $entry.Client ) {
'serviceClient'
{
if( $lines1 -contains $entry.IPAddress )
{
if( $ipStateHash.ContainsKey( $entry.IPAddress ) -eq $false )
{
$ipStateHash.Add( $entry.IPAddress, $entry.TimeStamp )
}
}
}
'Unregistered'
{
if( $ipStateHash.ContainsKey( $entry.IPAddress ) -eq $true )
{
$start = $ipStateHash.Get_Item( $entry.IPAddress )
$ipStateHash.Remove( $entry.IPAddress )
$timespan = $entry.TimeStamp - $start
$logArray += [pscustomobject]#{
IPAddress = $entry.IPAddress
Start = $start
End = $entry.TimeStamp
TimeSpan = $timespan
}
}
}
}
}
$logArray | ForEach-Object -Process {
display-span -logSpan $_
}
"IPs that weren't Unregistered:"
$ipStateHash.GetEnumerator() | Sort-Object -Property TimeStamp | ForEach-Object -Process {
'{0} ==> {1}' -f $nameHash.Get_Item( $_.Key ), $_.Value
}
Using your updated data files from above, the script outputs:
123.456.789.189:12345 (BOB) ==> 7/29/2015 6:00:13 AM
123.456.789.189:12345 (BOB) ==> 7/29/2015 6:00:19 AM
Start = 7/29/2015 6:00:13 AM, End = 7/29/2015 6:00:19 AM, diff = 00:00:06
222.222.222.444:56789 (ALICE) ==> 7/29/2015 6:00:18 AM
222.222.222.444:56789 (ALICE) ==> 7/29/2015 6:00:22 AM
Start = 7/29/2015 6:00:18 AM, End = 7/29/2015 6:00:22 AM, diff = 00:00:04
451.200.111.321:55555 (TOM) ==> 7/29/2015 6:20:03 AM
451.200.111.321:55555 (TOM) ==> 7/29/2015 6:21:19 AM
Start = 7/29/2015 6:20:03 AM, End = 7/29/2015 6:21:19 AM, diff = 00:01:16
IPs that weren't Unregistered:
BOB ==> 7/29/2015 6:01:00 AM