Friday, March 24, 2017

Bypassing Password Complexity Update...Case Closed

Upon further investigation, and trying many code snippets, I have concluded there is no way ( that I know of) to get around password complexity using PowerShell. 

This is good news!  If there was a way for a script geek like me to get around the group policy then Windows Server and Active Directory would be in serious trouble.



Wednesday, March 22, 2017

SQL Database Enumeration Script Update Part I

So, this SQL Instance Database enumeration script has been taking up all my free time.  This process is like running down a hallway with low hanging pipes.  I think I have the issues resolved and, PING, I hit one of the pipes.  Here is what I have to pull severs and instances:

foreach($Name in $names) {

$result = Test-Connection -ComputerName $Name.name -Quiet

if ($result) {

$objReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Name.name)

$objRegKey= $objReg.OpenSubKey("SOFTWARE\\MICROSOFT\\MICROSOFT SQL SERVER" )

if ($objRegKey.GetValue("InstalledInstances")) {

$instances = $objRegKey.GetValue("InstalledInstances")

if ($instances.Count -gt 0) {

foreach($i in $instances) {

if ($i -match 'MSSQLSERVER') {

$output = $Name.name

} Else {

$output = $Name.name + '\' + $i




}
} #$output | out-file -Append server_instance.csv

#$output | out-file -append server_instance.csv

} else { $output = $Name.name } $output | out-file -Append server_instance.csv


}

}

}

This line $result = Test-Connection -ComputerName $Name.name -Quiet checks if the server is online.  This verification shortens the number of servers in the output file.  If $result is true, the next level is initiated.

This line  $objReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Name.name)     adds registry information for the remote server to the $objReg variable.

This line  $objRegKey= $objReg.OpenSubKey("SOFTWARE\\MICROSOFT\\MICROSOFT SQL SERVER" )   adds the registry key for SOFTWARE\MICROSOFT\MICROSOFT SQL SERVER in the $objRegKey variable

This line if ($objRegKey.GetValue("InstalledInstances")) checks if the INSTALLEDINSTANCES key is present.  If it is present then the  $instances = $objRegKey.GetValue("InstalledInstances")  code loads the instances into the $instances variable.   

The next line if ($instances.Count -gt 0) checks if there are instances for the server.  I found that there will be no instances listed if the server is using the default MSSQLSERVER instance.  In this case the database script (which I will post later) will only need the server name and not server name\instance (i.e., sqlprd\mssqlserver). 

If there are instances in $instances, then the instance is checked for MSSQLSERVER.  If true, then only the server name is put in the $output variable.  Else, the server name and instance are put in the $output variable in the servername\instance format.

At the end the contents of the $output variable is written to the csv file.

This script works...for the most part.  I have found that one of my SQL server doesn't have all the instances listed.  I'm trying to figure this out today.

So, feel free to use this script.  NOTE: it is not perfect but is significantly better than what I had a week ago.

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