Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Check passwords, output to CSV 1

Status
Not open for further replies.

disturbedone

Vendor
Sep 28, 2006
781
AU
I'd like to import a CSV with a list of parents and check their password (default is set to a generic one) to see if they've changed it and output the results to another CSV. This is to show me all users who have not changed their password from the default.

I found a script online that I've modified. It works 99% correctly.

Code:
##Required for AD Support
Import-Module activedirectory

$ApplicationPath = "C:\Scripts\"
$CSVFile = $ApplicationPath + "parents.csv"
$LogFile = $ApplicationPath + "ParentPasswordsLog.txt"
$ResultsCSV = $ApplicationPath + "ParentPasswordsResults.csv"

import-csv $CSVFile | foreach {

	$UserName = $_.Username
	$Password = $_.Password
	$Domain = $env:USERDOMAIN

Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $ct,$Domain
$pc.ValidateCredentials($UserName,$Password)

    IF ($pc.ValidateCredentials($UserName,$Password) -ne "True") 
	{ $UserName,$pc.ValidateCredentials($UserName,$Password) | out-file $ResultsCSV }}

This outputs to a CSV and only outputs those where the result is false (ie it is still the default password). But it outputs the username on one line and and the result (False) on another. It has not put a , to make it a CSV. I've also tried the Export-CSV command but it doesn't work properly.

Any ideas how I can get this to work?
 
Why is $pc.ValidateCredentials($UserName,$Password) on a line by itself? You should assign it to a variable and add missing quotes to your CSV output line, so your code looks something like this:

Code:
##Required for AD Support
Import-Module activedirectory

$ApplicationPath = "C:\Scripts\"
$CSVFile = $ApplicationPath + "parents.csv"
$LogFile = $ApplicationPath + "ParentPasswordsLog.txt"
$ResultsCSV = $ApplicationPath + "ParentPasswordsResults.csv"

import-csv $CSVFile | foreach {

	$UserName = $_.Username
	$Password = $_.Password
	$Domain = $env:USERDOMAIN

Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $ct,$Domain
$PasswordChanged = $pc.ValidateCredentials($UserName,$Password)

    IF ($PasswordChanged -ne "True") 
	{ "$UserName,$PasswordChanged" | out-file $ResultsCSV }}


-Carl
"The glass is neither half-full nor half-empty: it's twice as big as it needs to be."

[tab][navy]For this site's posting policies, click [/navy]here.
 
Forgot to mention that if you are trying to compile a list in $ResultsCSV, then you need to specify the -Append parameter for out-file. Otherwise, the contents of the CSV file will constantly get overwritten.

Code:
"$UserName,$PasswordChanged" | out-file $ResultsCSV -Append

-Carl
"The glass is neither half-full nor half-empty: it's twice as big as it needs to be."

[tab][navy]For this site's posting policies, click [/navy]here.
 
That is outputting "False" regardless of whether the password in the input CSV is wrong or not. It is also not outputting the username.

My test input CSV has just 2 entries:
Code:
1234,passwordcorrect
4321,passwordwrong

The output CSV shows:
Code:
,False
,False

If I change the line to:
Code:
IF ($PasswordChanged -eq "False")
I get no output file.
If I change the line to:
Code:
IF ($PasswordChanged -eq "True")
I get no output file.
If I change the line to:
Code:
IF ($PasswordChanged -ne "True")
I get an output file but both lines say ,False.

So there are 2 issues now:
[ol 1]
[li]Something in the new code makes it not detect correctly in the IF statement[/li]
[li]It does not output the username[/li]
[/ol]
I'll continue to dig to see if I can work out why. Any ideas?
 
My bad :(

The input CSV had a column heading with a slightly different name that Username so the $UserName = $_.Username was the problem.

The final code which works perfectly is:

Code:
##Required for AD Support
Import-Module activedirectory

$ApplicationPath = "C:\Scripts\CheckParentPasswords\"
$CSVFile = $ApplicationPath + "parents.csv"
$ResultsCSV = $ApplicationPath + "ParentPasswordsResults.csv"

import-csv $CSVFile | foreach {

	$UserName = $_.Username
	$Password = $_.Password
	$Domain = $env:USERDOMAIN

Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $ct,$Domain
$PasswordChanged = $pc.ValidateCredentials($UserName,$Password)

    IF ($PasswordChanged -ne "True") 
	{ "$UserName,$PasswordChanged" | out-file $ResultsCSV -Append }}
 
Just revisiting this and it's actually not working as I want it.

It's creating a file called ParentPasswordResults.csv that contains data (when opened in a text reader) of:
Code:
10266,True
10365,True
10565,True
10667,True
10842,True
11506,True
but when opening it with Excel is has eg 10365,True in a single cell. It's not using the , as a delimiter.

Opening Excel, selectint 'Open' and finding the file treats it like a text file and asks if you want to find a delimiter character.

Just did a bit of searching and I found that I needed to put the following:
Code:
ut-file $ResultsCSV -Append [b]-Encoding ASCII[/b]
for it to output to a non-Unicode file. If anyone comes looking with the same problem I wanted to let others know.
 
Ok, so that works when importing a CSV. Now I'm trying to query AD directly (instead of importing a CSV) and have struck a strange issue. I can't find much about it online - the one suggestion I found didn't seem to make too much difference.

Below is a test script that just outputs to screen not CSV as will be the eventual outcome.
Code:
###Requires Powershell 2.0 and .NET3.5

###Required for AD Support
Import-Module activedirectory

# List email recipients who should receive the log file
$emailrecipients = "me@somewhere.com

$ApplicationPath = "C:\Scripts\ParentCheckPasswords\"
$CSVFile = $ApplicationPath + "parents.csv"
$ResultsCSV = $ApplicationPath + "ParentPasswordsResults.csv"

### Deletes previous results file if it already exists
if(Test-Path $ResultsCSV)
   {
        Remove-Item $ResultsCSV
   }


$users = $i = $null
### Finds all parent users
$USERS = Get-ADUser -SearchBase "OU=PARENTS, OU=USERS, DC=domain, DC=local" -filter *

IF ($USERS -eq $Null)
	{ Send-MailMessage –From server@somewhere.com –To $emailrecipients –Subject "Parent password change check" –Body "No parents found in the OU. This is a problem." –SmtpServer mail.somewhere.com
	}
ELSE {

 ForEach($user in $users) 
  { 
	$Password = "Password1"
	$Domain = $env:USERDOMAIN

Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $ct,$Domain

try {
    if($pc.ValidateCredentials($User, $Password)) {
        Write-host "good"
    }
    else {
        Write-host "bad"
    }
}
finally {
    $pc.Dispose()
}
    Start-Sleep -s 5
}
}

### Create the mail message and add the $Results.csv text file as an attachment###
#Send-MailMessage –From server@somewhere.com –To $emailrecipients –Subject "Parent password change check" –Body "Attached is a list of parents who have not changed their password from default" -Attachment $ResultsCSV –SmtpServer mail.server.com
The one suggestion I could find was the addition of the try { etc code with the import part being the $pc.Dispose() to clear out any remains of the previous attempt. This didn't seem to make much difference. I then put in the Start-Sleep -s 5 line to see if adding a delay improved things but it didn't.

The output was:
Code:
PS C:\Scripts\ParentCheckPasswords> .\TESTcheckparentpasswords.ps1
good
good
Exception calling "ValidateCredentials" with "2" argument(s): "A local error occurred."
At C:\Scripts\ParentCheckPasswords\TESTcheckparentpasswords.ps1:39 char:8
+     if($pc.ValidateCredentials($User, $Password)) {
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : LdapException

good
good
good
Exception calling "ValidateCredentials" with "2" argument(s): "A local error occurred."
At C:\Scripts\ParentCheckPasswords\TESTcheckparentpasswords.ps1:39 char:8
+     if($pc.ValidateCredentials($User, $Password)) {
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : LdapException

Exception calling "ValidateCredentials" with "2" argument(s): "A local error occurred."
At C:\Scripts\ParentCheckPasswords\TESTcheckparentpasswords.ps1:39 char:8
+     if($pc.ValidateCredentials($User, $Password)) {
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : LdapException

good
good
Exception calling "ValidateCredentials" with "2" argument(s): "A local error occurred."
At C:\Scripts\ParentCheckPasswords\TESTcheckparentpasswords.ps1:39 char:8
+     if($pc.ValidateCredentials($User, $Password)) {
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : LdapException

Exception calling "ValidateCredentials" with "2" argument(s): "A local error occurred."
At C:\Scripts\ParentCheckPasswords\TESTcheckparentpasswords.ps1:39 char:8
+     if($pc.ValidateCredentials($User, $Password)) {
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : LdapException
So there are 2-3 successful attempts and then 1-2 failures. It's not completely consistent.

Any ideas how to stop this error?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top