Monday, March 20, 2017

Running Behind

I haven't posted in a couple days due to projects at work.  I'll get something new out later this week.

Wednesday, March 15, 2017

My Next Challenge...Bypassing Password Complexity

I have taken up a new challenge to rest my brain from the SQL enumeration scripts.  I am looking into the possibility of changing a user's password in a domain that has password complexity enabled.  Also, password granularity is also disabled.

Now, I don't think I will be able to get this to work since password policies are set by Group Policy Objects (GPOs) but we currently have a need to create accounts that go against our password policies.  Big security issue?  Yep.  Will I share the code?  Maybe. But it should be known that my current employer is not responsible for which code I post to this blog as long as I don't breach any security measures or policies.

Stay tuned. 

Monday, March 13, 2017

I have the SQL Instance/Database Enumeration script on the ropes

I have made some progress in my quest to create a script that will list the SQL server, the instance, and the databases in the instance.  I asked a couple of my colleagues (thank you Mike and Josh) to take a look the code and they gave some recommendations that helped considerably.

Now, all I need to do is to get the server and instance name in the same file as the databases.  I think I will have it completed by the end of the week.

More soon...

Wednesday, March 8, 2017

Best Practice...Script Documentation

If you are like me you hate writing documentation.  Have you heard yourself say, "I know how the process/script/equipment works.  Why do I have write it down?"  Well, the reality is that you may not be managing the said process/script/equipment forever.  Documentation is the right thing to do.  It makes it easier for others to follow the flow of a script, it can give examples of how to run the script, and it allows the coder to keep track of changes made over the course of the scripts lifetime.

Powershell is easy to script and you can use the following template get started:

<#

.SYNOPSIS

This is a brief description of what the script/function does

.DESCRIPTION
This is a more detailed explanation of the script/function

.PARAMETER name
An explanation of a specific parameter (if used).  Replace 'name' with the parameter name

.EXAMPLE
This shows examples of how to run the script/function.  You can have multiple .EXAMPLE sections if you like to show more than one example


.NOTES
This section is for any miscellaneous information regarding the script/function


.LINK
This section would contain a URL (beginning with either HTTP:// or HTTPS://) that can be a cross-reference to other help sites.  You can have multiple .LINK sections
#>


I also like to add a VERSION HISTORY section to the script.  That way I can keep track of changes that have been made to the script.  To add version history you use the following within the <# #>:
   # VERSION HISTORY
  
   # Version 1.2 (January 1, 2017)
   # Changed the GET-ADUser statement to include both domains

You will see that some of the scripts I have put on this blog do not follow this standard.  That is because some of these scripts are not in Production.  If I create a script that will be used by people other than myself, I will use my template.

I hope you find this helpful.  Your boss and colleagues will appreciate the effort.
  

Who Manages Who?

I work for a medium size company.  There are a number of office and production employees.  Sometimes it is a challenge to determine the manager of office personnel.  Below is a script I created that reads information from Active Directory and generates a .csv file that contains the employee's name and their manager:
<#



.SYNOPSIS

Script that generates employee/manager report



.DESCRIPTION

This script stores all user accounts from specific OU into a variable. This information is used to create a report that contains

an employee and the employee's manager



.NOTES

Name: employee_manager.ps1

Author: Mike Egan

DateCreated: 2015-12-4

Version: 1.1

#VERSION HISTORY

#

# Version 1.2 (March 8, 2017)

# Changed the $Results declaration to include a ',' between $uName and $uMgr

# Added $filedata = import-csv $outfile -header Employee, Manager so the report would have

# the proper headings

# Added $filedata | export-csv $outfile -NoTypeInformation so the output file had the proper

# headings





#>
 
$userlist = get-aduser -filter * -properties * -searchbase "OU=<organizational unit>,DC=<domain>,DC=<domain>" | select name,manager #| export-csv employee_manager.csv

$outfile = "c:\downloads\test.csv"

foreach ($usr in $userlist) {

#write-host $usr.name

if (!($usr.manager -eq $null)){

$trimmed_mgr = $usr.manager.substring(3)

$var1 = $trimmed_mgr.split(",")

$uName = $usr.name

$uMgr = $var1[0]

$results = "$uName,$uMgr"

} $results | out-file -append $outfile

$results = $null # End IF

} # End ForEach

$filedata = import-csv $outfile -Header Employee , Manager

$filedata | export-csv $outfile -NoTypeInformation

In the get-aduser command, an example of a -searchbase would be "OU=users,DC=Microsoft,DC=Net"

The output of the script will be the c:\downloads\test.csv.  NOTE: you may want to delete this file each time you run this script or the file will be full of duplicate information.

As you can see I commented out write-host $usr.name.  I used this command during the building and testing of this script.  You can remove the line if you like.

I hope you find this script helpful

Deleting Files Over 30 Days

I have had a few requests come in asking to create a job that will delete files, in a specific folder, that are older than 30 days.  This was a relatively simple script to write, here it is:
$fileList = get-childitem -path <\\<server name>\<path>

foreach ($files in $filelist) {

if ($files.LastAccessTime.Date -lt (get-date).adddays(-30)) {

#write-host -ForegroundColor green $files.FullName

Remove-Item $files.FullName



} # end IF

} # end foreach

You can adjust the number of days by changing the (get-date).adddays(-30))   from -30 to whatever number of days you choose.

I have been able to use this cmdlet for many different jobs.  That's what I like about Powershell...you can reuse code for different applications.

I hope you found this useful.

Tuesday, March 7, 2017

How come my account locked up again?

We recently had a user who changed their network password but his account kept getting locked out.  We have a manual and tedious method of finding where the lockout is occurring.  I took it upon myself to find a way find the lock out location using Powershell.  Here are two scripts I found to help us find the location:

Get-LockedOutUser
#Requires -Version 3.0






<#

.SYNOPSIS

Get-LockedOutUser.ps1 returns a list of users who were locked out in Active Directory.

.DESCRIPTION

Get-LockedOutUser.ps1 is an advanced script that returns a list of users who were locked out in Active Directory

by querying the event logs on the PDC emulator in the domain.

.PARAMETER UserName

The userid of the specific user you are looking for lockouts for. The default is all locked out users.

.PARAMETER StartTime

The datetime to start searching from. The default is all datetimes that exist in the event logs.

.EXAMPLE

Get-LockedOutUser.ps1

.EXAMPLE

Get-LockedOutUser.ps1 -UserName 'mikefrobbins'

.EXAMPLE

Get-LockedOutUser.ps1 -StartTime (Get-Date).AddDays(-1)

.EXAMPLE

Get-LockedOutUser.ps1 -UserName 'mikefrobbins' -StartTime (Get-Date).AddDays(-1)

#>
 

 
[CmdletBinding()]

param (

[ValidateNotNullOrEmpty()]

[string]$DomainName = $env:USERDOMAIN,

[ValidateNotNullOrEmpty()]

[string]$UserName = "*",

[ValidateNotNullOrEmpty()]

[datetime]$StartTime = (Get-Date).AddDays(-3)



)
 
Invoke-Command -ComputerName (

[System.DirectoryServices.ActiveDirectory.Domain]::GetDomain((

New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $DomainName))

).PdcRoleOwner.name



) {
 
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4740;StartTime=$Using:StartTime} |

Where-Object {$_.Properties[0].Value -like "$Using:UserName"} |

Select-Object -Property TimeCreated,

@{Label='UserName';Expression={$_.Properties[0].Value}},

@{Label='ClientName';Expression={$_.Properties[1].Value}}

} -Credential (Get-Credential) |

Select-Object -Property TimeCreated, UserName, ClientName

This script will require administrative credentials.  Here is the output from the script:
The UserName is the account that is locked out.  The ClientName is the server that has locked out the account.

Get-LockedOutInfo
## Define the username that's locked out

$username = '<user name>' # put in user name




## Find the domain controller PDCe role
 
 
$Pdce = (Get-ADDomain).PDCEmulator




## Build the parameters to pass to Get-WinEvent
 
 
$GweParams = @{

‘Computername’ = $Pdce

‘LogName’ = ‘Security’

‘FilterXPath’ = "*[System[EventID=4740] and EventData[Data[@Name='TargetUserName']='$Username']]"



}

 
 
## Query the security event log
 
 
$Events = Get-WinEvent @GweParams

$Events[0].Properties[0].Value

$Events[0].Properties[1].Value



This script will look for lock out information for a specific user.  The line $Events[0].Properties[0].Value gives the user name.  $Events[0].Properties[1].Value gives the server that has locked out the account.

I would like to take full credit for the code but, as you know, scripters borrow code from others.  I appreciate the people who have created the code and I hopefully will be able to have my code used by others.

I hope you find these scripts helpful.