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.
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...
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.
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
<#
.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.
$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.
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.
Subscribe to:
Posts (Atom)
