Category Archives: Batch and Script

Powershell – Rename Local Admin Account OR Ecuritysay Oughthray Obscurityway

This PowerShell script looks for the local Administrator account (as a member of the local Administrators group) and renames it. Then it creates a bogus local administrator account with a 32 character password that next expires and is not a member of any groups.

Likely this will only catch your local admins who have not had their morning coffee yet, but you can audit and know that any attempt to logon to Administrator is bad.

This script renames the Administrator to Admin (not very creative yes, if you don’t like that change $NewAdminName to something better. I suggest Ted.

The script takes input from a file c:\servers.csv that has a header of “ComputerName” and then one per line the list of server names you want to check and adjust.

If someone really wants more explanation post a comment.

Thanks to the creator of the password generator (Adam Bell) but I wish I noticed the comment about the break sooner. I have they adjusted code in my script.

function create-complexpassword
 {
 #  *** Unable to generate complex password less then 5 chars ***
 #  ASCII data taken from http://msdn2.microsoft.com/en-us/library/60ecse8t(VS.80).aspx
  
 Param (
   [int]$PassLength
   )
  
 #  Let's work out where our 3 complex characters will be inserted in the password...
   [int]$mark = ($PassLength/3)
   $ComplexChar = @("marker") 
  $ComplexChar[0] = $mark
   $ComplexChar = $ComplexChar+($ComplexChar[0] + $mark)
   $ComplexChar = $ComplexChar+(($ComplexChar[1] + $mark) -1)
  
   $Password = $null
   $rnd = new-object random
  
 #  "i" is our counter while we make the password, one char at a time.
   $i = $Password.length
   do 
    {
       switch ($Password.length)
         {
           $ComplexChar[0]
             {
               # Make this character a Numeric
               $password = $password+([char]($rnd.next(48,57)))
             
             }
           
           $ComplexChar[1]
             {
               # Make this character a LowerAlpha
               $password = $password+([char]($rnd.next(65,90)))
             }
           
           $ComplexChar[2]
             {
               # Make this character a Upper Alpha
               $password = $password+([char]($rnd.next(97,122)))
             }
             
           default
             {
               # In case this is used in a DCPromo answer files, theres a few chars to 
              # avoid: Ampersand, Less than, double quote and back slash
               $NextChar = $rnd.next(33,123)
               
               switch ($nextChar)
                 {
                   34 {break}
                   38 {break}
                   60 {break}
                   92 {break}
                   default 
                    {
                       $Password = $Password+([char]$nextChar)
                   
                     }                
                 }
             }
         }
       $i++
	    } 
  Until ($Password.length -eq $PassLength)
   return $Password
   }
cls

$NewAdminName="Admin"
$InputServers = Import-Csv “c:\servers.csv”
$Servercount = 1
$ServerCountTotal = $InputServers.Count

$InputServers | ForEach-Object {
			$_.computername
			$computer=$null
			$Group=$null
			$LocalAdministrators=$null
			$Administrator=$null
			$Admin=$null
			$PasswordString=$null
			$computer = [ADSI]("WinNT://" + $_.computername + ",computer")
			$Group = $computer.psbase.children.find("Administrators")
			$LocalAdministrators= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
			$Admin = $computer.psbase.children.find($NewAdminName) 
			$Administrator = $computer.psbase.children.find("Administrator") 
			$PasswordString=create-complexpassword(32)
			 If ($Administrator) 
			 {
			  if (($LocalAdministrators -contains "Administrator" ) -and (!$Admin))
			  	{
				$Administrator.Rename($NewAdminName)
				Start-Sleep -Seconds 1
				$computer=$null
				$Group=$null
				$LocalAdministrators=$null
				$Administrator=$null
				$Admin=$null			
				$computer = [ADSI]("WinNT://" + $_.computername + ",computer")
				$Group = $computer.psbase.children.find("Administrators")
				$LocalAdministrators=$null
				$LocalAdministrators= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
				$Admin = $computer.psbase.children.find($NewAdminName)
				$Administrator=$null
				$Administrator = $computer.psbase.children.find("Administrator") 
				}
			 }
			 If (!$Administrator)
			 	{
				$objUser = $Computer.Create("User","Administrator")
			 	$objUser.setpassword($passwordstring)
				$objUser.SetInfo()
				$objUser.userflags = $objUser.userflags + 65536 # flag - never expires 
			 	$objUser.SetInfo()
				$objUser.Description="Built-in account for administering the computer/domain"
			 	$objUser.SetInfo()
				$objUser.FullName=""
			 	$objUser.SetInfo()
				}
 }

Powershell – Add users to local groups OR Sounds like a job for group policies

Today I needed to add a couple of AD users to the local administrators group on a number of servers….. and I am not allowed to use a GPO to do it.

Not wanting to manually connect to every machine I used the following powershell script

cls

$InputServers = Import-Csv “c:\servers.csv”

$InputUsers = Import-Csv “c:\users.csv”

$Servercount = 1

$ServerCountTotal = $InputServers.Count

$InputServers | ForEach-Object {

$ServerTemp=$_.ComputerName

“Starting ” + $Servercount + ” of ” + $Servercounttotal + ” : ” + $ServerTemp

$InputUsers | ForEach-Object {

$objUser = [ADSI](“WinNT://” + $_.Username )

$objGroup = [ADSI](“WinNT://” + $ServerTemp +”/Administrators”)

$objGroup.PSBase.Invoke(“Add”,$objUser.PSBase.Path)

}

“Complete ” + $Servercount + ” of ” + $Servercounttotal + ” : ” + $ServerTemp

$Servercount++

}

“Script Complete”

 

The script looks for 2 CSV files in the root of c:\

Servers.csv has a header of “ComputerName” and then a list of servers you want to affect one per line.

Users.csv has a header of “UserName” and then a list of user names (OLD FORMAT) Domain/User one per line.

 

Enjoy

 

Batch clearing of logs – everyday spring cleaning.

The Issue:

Lets just say hypothetically someone likes to log things, they like to log them a lot. Lets also say as the admin of the server they are logging to you don’t like to have your server crash when it runs out of disk space, and the only thing you like less than that is to chase them and make them clean up.


The Solution :

A script scheduled to run everyday.  In this example we will be cleaning out anything in d:\syslog

date /t >>c:\scripts\deletesyslog\%date:~-10,2%%date:~-7,2%%date:~-4,4%.log”
Time /t>>c:\scripts\deletesyslog\%date:~-10,2%%date:~-7,2%%date:~-4,4%.log”
echo Scan Started>>c:\scripts\deletesyslog\%date:~-10,2%%date:~-7,2%%date:~-4,4%.log”

FORFILES -p D:\Syslog\ -s -d -10 -c “CMD /C echo @PATH@FILE>>c:\scripts\deletesyslog\%date:~-10,2%%date:~-7,2%%date:~-4,4%.log”

FORFILES -p D:\Syslog\ -s -d -10 -c “CMD /C del /F /Q @FILE”

echo SCAN Complete>>c:\scripts\deletesyslog\%date:~-10,2%%date:~-7,2%%date:~-4,4%.log”
TIME /t>>c:\scripts\deletesyslog\%date:~-10,2%%date:~-7,2%%date:~-4,4%.log”

 The first 3 lines create a log file in c:\scripts\deletesyslog and log the date and time the script was run, the 4th line logs what is about to be deleted.   The last 2 lines log the time it finished.

Line 5 is the only one that really does anything so If you don’t really care about all this sissy logging that all you need.

Forfiles

-p (path)

-s recurse subdirectories

-d -10 selects files with a modified date of greater than 10 days (alter the 10 if that’s not good for you, remember to alter the matching 10 on the logging line above)

“CMD /C del /F /Q @FILE” is the actual delete command

Enjoy