![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
|
Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
br> br> |
| |||||||
![]() |
| | Thread Tools | Display Modes |
| | #1 (permalink) |
| Guest | Working with arrays I have having the following problem: I have an array say $events i obtained from get-eventlog (which say returns a number of events matching the criteria set) when displayed it will give something like {passwordlastset: 15\12\70 callerusername: administrator} I am basically trying to write only where the passwordlastchanged criteria match and the user did not change the password himself from similar code to below: foreach ($objuser in $AD) { foreach ($event in $events) { $P = $event.passwordlastset $N = $event.callerusername IF ($passwordlastsetobtainedfromADSI -eq $P) -and ($N -ine $usersnameobtainedfromADSI) { write-host "$N" + " was the last person to change the password of " + "$usersnameobtainedfromADSI" } } } The problem I have is it will hit the first person who meets the criteria and write as expected but also the same info for each and every user thereafter - any help would be much appreciated as I have tried a number of things all to no avail -- jobbsy@xxxxxx |
My System Specs![]() |
| | #2 (permalink) | ||||||||||||
| Guest | Re: Working with arrays It's hard to say just from viewing the code sample. You can try to assign the variables to $null or "" in each iteration. BTW, -ine (case-insensitive comparison) is the same as -ne. Also, if $N and $usersnameobtainedfromADSI are strings then you don't need to concatenate the variables: write-host "$N" + " was the last person to change the password of " + "$usersnameobtainedfromADSI" You can simply write: write-host "$N was the last person to change the password of $usersnameobtainedfromADSI" ----- Shay Levi $cript Fanatic http://scriptolog.blogspot.com
| ||||||||||||
My System Specs![]() | |||||||||||||
| | #3 (permalink) | ||||||||||||||||||||||||
| Guest | Re: Working with arrays Thanks Shay there's nothing else I believe coming into the second loop that would effect it - I hav tried with both $null and "" and the code works fine until there is an earlier entry picked up - I test this by changing the password of same user in quickish succesion and running against a certain -newest no of eventlog entries knowing I will pick them both up - therefore the earlier one shouldnn't match the passwordlastset adsi value, although it would match -ne to username). Yes thanks for the write-host and -ieq tip. -- jobbsy@xxxxxx "Shay Levi" wrote:
| ||||||||||||||||||||||||
My System Specs![]() | |||||||||||||||||||||||||
| | #4 (permalink) | ||||||||||||||||||||||||||||||||||||
| Guest | Re: Working with arrays What are the types of $N, $P, etc? (e.g $N.gettype()) Doe's the same happens when you run: $N=@{name="CallerUserName";expression={$_.callerusername}} $P=@{name="PasswordLastSet";expression={$_.passwordlastset}} $ADSIUser =@{name="ADSIUserName";expression={$usersnameobtainedfromADSI}} $events | select $N,$P,$ADSIUser | format-table -auto ----- Shay Levi $cript Fanatic http://scriptolog.blogspot.com
| ||||||||||||||||||||||||||||||||||||
My System Specs![]() | |||||||||||||||||||||||||||||||||||||
| | #5 (permalink) | ||||||||||||||||||||||||||||||||||||
| Guest | Re: Working with arrays Thanks for your help Shay I was able to figure it out (I needed the 5thField outside of the events loop from my finished code below - you were right without seeing all the code you could not have troubleshooted that - but appreciated your input - I'm sure this is not the most professional code ever but it works! - Thanks again #INITIALISATION SECTION #---------------------- #Clear the Windows command console screen Clear-Host #CONSTANTS SECTION #----------------- $strDate = get-date -uformat "%Y-%m-%d" $CSVFilePath = 'c:\Documents and Settings\All Users\Desktop\SwapClearITD_users_'+$strDate+'.csv' #Delete previous file if exists $RetVal = Test-Path 'c:\Documents and Settings\All Users\Desktop\' | where-object {$_.name -like "*.CSV"} If ($RetVal = 'True') { Remove-Item 'c:\Documents and Settings\All Users\Desktop\*.CSV' } #Creates new dated file and specifies header for CSV. $strOutputString = "User,Member Of Group,Account Created,Password last changed" $strOutputString | out-file -Width 2147483647 -filepath $CSVFilePath -encoding ascii #Retrieve Events for Administrator Password Changes [regex]$regEx = ('\:\s+') $events = @() get-eventlog Security -newest 2000 | where {$_.eventID -eq '642'} | % { $obj = new-object psObject switch -regex ($_.message.split("`n")) { '^\s*Password Last Set\:' { add-member NoteProperty -name PasswordLastSet ` -value $($regEx.split($_)[1]).trim() -in $obj } '^\s*Caller User Name\:' { add-member NoteProperty -name CallerUserName ` -value $($regEx.split($_)[1]).trim() -in $obj } } $events += $obj } #FUNCTIONS & FILTERS SECTION #---------------------------- #MAIN PROCESSING SECTION #----------------------- $Dom = 'LDAP://OU=test,DC=vmware,DC=vm' $Root = New-Object DirectoryServices.DirectoryEntry $Dom $i=0 # Create a selector and start searching from the Root of AD $selector = New-Object DirectoryServices.DirectorySearcher $selector.SearchRoot = $root $selector.pagesize = 1000 $adobj= $selector.findall() |` where {$_.properties.objectcategory -match "CN=Person"} foreach ($person in $adobj) { $prop=$person.properties $i++ $1stField = "$($prop.name)" + "," # $2nd Field - Member Of #--------------------------------------------------------- IF ("$($prop.memberof)" -match "CN=*") { #Remove the "CN=, OU=TEST," etc & just keep name of group at front of DN $s = "$($prop.memberof)" $firstdivofDN,$seconddivofDN,$thirddivofDN = ([regex]'=(.+?),').matches($s) | foreach {$_.Groups[1].Value} $2ndField = "$firstdivofDN" + "," } ELSE { $2ndField = "****NOT A MEMBER OF A GROUP****" + "," } # $3rd Field - date When account was created #------------------------------------------ $AC = $($prop.whencreated) $AccountCreated = "{00:dd}/{00:MM}/{0000:yyyy} {0:hh}:{0:mm}:{0:ss}" -f($AC) $3rdField = "$AccountCreated" + "," # $4th Field - Password Last Set #---------------------------------------------------------- #Convert the large Integer format into a readable date $LI = [datetime]::FromFileTimeUTC( $($prop.pwdlastset[0]) ) $PWLSet = "{00:dd}/{00:MM}/{0000:yyyy} {0:hh}:{0:mm}:{0:ss}" -f ($LI) $4thField = "$PWLSet" + "," # $5th Field - Was Administrator last person to change Password? #-------------------------------------------------------------- $5thField = "" IF ("$AccountCreated" -match "$PWLSet") { $5thField = "****PASSWORD NOT CHANGED SINCE ACCOUNT SETUP****" + "," } ELSE { Foreach($event in $events) { # from constants section at start $E = $event.PasswordLastSet $N = $event.CallerUserName IF (("$E" -match "$PWLSet") -and ("$N" -ne "$($prop.name)")) { $5thField = "****PASSWORD last Changed by " + "$N" + "****" + "," } } } $strOutputString = "$1stField" + "$2ndField" + "$3rdField" + "$4thField" + "$5thField" $strOutputString | out-file -filepath $CSVFilePath -encoding ascii -append } -- jobbsy@xxxxxx "Shay Levi" wrote:
| ||||||||||||||||||||||||||||||||||||
My System Specs![]() | |||||||||||||||||||||||||||||||||||||
| | #6 (permalink) | ||||||||||||||||||||||||||||||||||||
| Guest | Re: Working with arrays Hi Jobbsy, Glad you could resolve it :-) Generally, I would avoid keeping/running files from any desktop, the path is too deep any you may encounter permission errors. 1. You can embed $strDate inside double quotes string and it will expand its value. $CSVFilePath = "C:\Documents and Settings\All Users\Desktop\SwapClearITD_users_$strDate.csv" 2. Test-Path determines whether all elements of a path exist. It checks for one file/directory based on leaf/container value of -pathType parameter. It doesn't check for ALL (*.CSV) files. If you want to delete all CSV files before starting use 'get-childitem -filter *.csv | remove-item -force' To test for a file existence use: test-path -path c:\scripts\$strDate.csv -pathType leaf For directory: test-path -path c:\scripts -pathType Container Execute 'get-help test-path -full' to get full available help 3. You can format dates easily with the -format operator, its much more concise then $AccountCreated assignment: PS > get-date -f "dd/MM/yyyy hh:mm:ss" 19/11/2007 11:36:08 The same can be applied when you retrieve events from a log file: PS > $e= get-eventlog application -new 1 PS> $e.TimeWritten -f "dd/MM/yyyy hh:mm:ss" 19/11/2007 11:36:08 4. '$AC = $($prop.whencreated)' is the same as '$AC = $prop.whencreated'. Generally, You use the $($prop.member) subexpression expansion notation when you need to expand the variable inside of a string. You can't write this: PS > write-host "PowerShell current culture is: $Host.CurrentCulture" PowerShell current culture is: System.Management.Automation.Internal.Host.InternalHost.CurrentCulture This works: PS > write-host "Working directory path is $($Host.CurrentCulture)" PowerShell current culture is: he-IL HTH ----- Shay Levi $cript Fanatic http://scriptolog.blogspot.com
| ||||||||||||||||||||||||||||||||||||
My System Specs![]() | |||||||||||||||||||||||||||||||||||||
| | #7 (permalink) | ||||||||||||||||||||||||||||||||||||
| Guest | Re: Working with arrays Thanks Shay I will sit down and go through your tips and certainly take them onboard My next challenge is to interrogate 2 DCs in a Domain - this script runs happily against one dc in a test domain - also as the security event log is liable to being overwritten I will have to save the csv files and loop through a number of historical ones to make sure info is accurate - I reckon it will probably be easier to combine the two output files after running on each DC - all this will be scheduled to run daily - that should test my knowledge! -- jobbsy@xxxxxx "Shay Levi" wrote:
| ||||||||||||||||||||||||||||||||||||
My System Specs![]() | |||||||||||||||||||||||||||||||||||||
![]() |
| Thread Tools | |
| Display Modes | |
| |
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Arrays | Jason Massie | PowerShell | 10 | 05-14-2008 07:37 AM |
| Arrays in Powershell | Daren Daigle | PowerShell | 2 | 12-03-2007 07:37 AM |
| Multidimensional arrays | Jacob | |||