Link to home
Start Free TrialLog in
Avatar of Dale Harris
Dale HarrisFlag for United States of America

asked on

Hashtable Import/Merge/Export Powershell

This is something I've attempted to do before, but did not succeed.  Now I'm asking for something pretty interesting and I haven't seen much written about it on Google or EE.

Simply put, I want to make a hash table with values like "John Smith", "2" and "Jane Doe", "4".  It starts by taking a survey of all the exchange mailboxes and whoever is over a certain amount of MBs, flags that user name and adds it to a temporary list.  This can be an array since it's only a bunch of names.  No numbers yet.  Here's where it gets interesting.  There will be a text file or csv, whichever is easier in a location accessible by the script.  Let's call it "C:\HashTable.csv".  It imports all the values from Hashtable.csv into a hashtable.  Then it goes down the line and says "If a person exists in this hash table, increment their corresponding value by 1".  Otherwise, just add them to the list, and give the key a value of 1.  So the key is the persons name (because it's unique), and the value is how many days we've found them full on the server.

I tried to use a text file that outputs their names into it, and then counts it all up.  That works but after a while the text file gets so sloppy, it's hard to read it.  And it also pretty large after a few days.

Hopefully someone can cook something up.  The hardest part I'm having is exporting the hashtable.  Once I export it, I suppose it would be easy to import it.  And even easier to do a "Does key exist" on the table, then if they do, increment their value by 1.  Should be a cakewalk, right?

This has been something plaguing me for a few months and I shelved it because I got sidetracked with other projects.  So whoever can fix this will get my 2000 points + my undying gratitude free of charge.

-Dale Harris
Avatar of Bryan Butler
Bryan Butler
Flag of United States of America image

How about the names in a DB and then querying to see how many days they are "full" using a select count(name) from table.  You could even add dates to the records for more details.  Another solution would be to store everyone in the DB and each record has the name and count.  You would add one to the count each time they show up in the daily log/csv.  
Or I guess you could use a flat file for the latter solution too.
Avatar of Dale Harris

ASKER

I can definitely see where you're going with it, but the purpose is to integrate it into my daily scripts.  I'm stuck with using tools native to PowerShell.

I'm also looking not just for a word answer, but actual code itself.
So using a flat file as a DB would work.  Continuing some code I've posted on here, the below code will keep a csv flat file with each row starting with the names and a then a "1"(checkmark) for each time they were "full".  Sounds you want to just keep a running total, in this case you would just add some code, but first, is this in the right direction?  (untested)

$aryCounts = Get-Content ".\counts.txt" 
$aryNames = Get-Content ".\allNames.txt" 
$iter1=0
$iter2=0
do {
  do {
      [regex]::Replace($aryCounts[$iter1], $aryNames[$iter2], "$0") >> temp.txt
      ",1`n" >>temp.txt #add comma and another "1" meaning full, and a newline
      iter2++
  } until  ($iter -eq $aryNames.length)
 
   $iter1++
} until ($iter -eq $aryCounts.length)

Open in new window

Ooops, this will give a "1" everytime...scratch that.  I think it would be:  

[regex]::Replace($aryCounts[$iter1], $aryNames[$iter2], "$0,1") >> temp.txt

Not sure if you need the newline.  If so...

[regex]::Replace($aryCounts[$iter1], $aryNames[$iter2], "$0,1`n") >> temp.txt
ASKER CERTIFIED SOLUTION
Avatar of BSonPosh
BSonPosh
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
BSonPosh,

I'm just about ready to head off of work.  Thanks for the tip.  I'll have to check it out tomorrow morning.  Don't give up on me yet :)

-Dale Harris
no rush on my side :) take your time
Excellent script.  Does he need to initialize $names?  Such as:

$names = Get-Content ".\allNames.txt"
yes... There is a good bit that should be added, but without the entire source I cannot provide a complete script.

I was hoping to illustrate the options he has :)
Options....that's the best way to go!  

That importcsv....very nice.
Yes... import-csv and import-xml are lifesavers
BSonPosh,

I've almost got it figured out (thank you so much), but I'm having a couple issues.

You may have typed it a little hasty.

The logic behind the loop replaces the $myobj information on each iteration without exporting to a csv.

So the fix behind this would be to either
A) Append to the csv file (takes more time to do this) or
B) Create a little custom object array

I tried to make $myobj[2] = " " | Select Name,Count work, but it threw an error.

What can I do to make this work for me?

-Dale Harris
# Get old list of names from file
$oldnames =  import-csv oldlist.csv
 
# Collection to store custom objects
$myobjs = @()
 
foreach($name in $names)
{
   # Get old count
   $oldcount = $oldnames | ?{$_.name -eq $name} | %{$_.count}
 
   # create custom object
   $myobj = "" | Select Name,Count
   $myobj.name = $name
   $myobj.count = $oldcount + 1
}
 
$myobjs | export-csv oldlist.csv -noType

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Getting the error message:

Method invocation failed because [System.Management.Automation.PSObject] doesn't contain a method named 'op_Addition'.
At line:1 char:11
+ $myobjs += <<<<  $myobj

So I'm thinking I'll have to do a force object type [something], or I'll have to do something other than just attempt to make $myobj get stored into $myobjs

-Dale Harris
BSonPosh,
 
Nevermind.  It worked once I had done the proper $myobjs = @() that you put in the top of the other script.  It's all good now.  I'll report back if I have any more issues.

Thanks.

-Dale Harris
Hows this going?
BSonPosh,

Sorry to keep you waiting.  I finally implemented the solution and it's working as I had hoped.  I'm going to close this question out with the assumption that if I need help to modify it later, I'll be putting in another question.

Thanks again for all the help!

-Dale Harris
Thanks again!  Just to give you an update, I'm leaving in a couple months, so if this is my last question before I go, I definitely would like to give you an emphatic thanks and I'm amazed that you give away your services for free to people like me :)

With all of your help, I was able to implement various scripts to streamline my job and do you remember that script we worked on where I was trying to make someone's expiration date take effect through Set-QADObject that you gave me the final answer to?  Well, we ended up losing 1300 accounts one day due to an abominable Gal Sync (I was not doing said Gal Sync), and because of that script I made from help with you, my co-worker and I were able to recreate all 1300 accounts in 10 hours.  That would've taken probably two days without a script and probably a bunch more errors.  I wish I could tell you more about it, but it's classified as SECRET unfortunately.  Anyways, just know that you, Brandon Shell, contributed to the overall readiness of the 3rd Brigade Combat Team, 4th Infantry Division in FOB War Eagle, Iraq.  When my bosses thought we were sunk, my (your) script helped get us back into the fight.

I salute you.

-Dale Harris
@Dale, I am glad I could help, but to compare what I do what you guys do on a daily basis it is a joke at best. You guys are true Heros. I imagine you guys often don't feel the appreciation from the ungrateful people back here running things, but I personally want to let you know. I appreciate you!