Thursday, September 17, 2020

Powershell: Change static DNS values on the fly

Problem = you have a metric crap ton of statically IP assigned windows machines, and you want to change their DNS settings. 

 I've seen much of this info posted elsewhere, but it feels like no one really puts it all together very well, so here's my own take on how to pull this particular trick off. 

First off, the commands needed to "set" new DNS values, want to know which "adapter" on a machine you're going to change, this is returned as a number value with a name of "interfaceindex". That number VARIES per machine. 

So the following can be run per machine, which will quickly find the proper adapter to adjust and adjust it:


******************Begin script********************

$adapter=get-netadapter | select -expandproperty interfaceindex

$newdns1="1.1.1.1"

$newdns2="2.2.2.2"

set-dnsclientserveraddress -interfaceindex $adapter -serveraddresses ($newdns1,$newdns2)

****************End script***********************


run interactively, these command would require elevation to execute, so plan for that in your deployment. 

This change is immediate, with no event log errors generated, or service outages caused. 


 



Friday, March 27, 2020

Powershell: Function: Convert CSV into auto-filtered XLSX files

The purpose of this powershell function is to be used as a means of within script generating report like files.

This function has been generalized for use under a variety of situations, but expect that so long as your data is broken out within the input CSV the result XLSX file should have:

- Top row - to last filled column is assumed to be a header row.
  - this row gets bolded, a filled in color, and the filters are set at this layer.

System executing a script that contains this function needs to have excel installed and working.

**********************script begin***************************************

Function CSVtoXLSX
{
    [cmdletbinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0)]
        [string]$arg1,
       
        [Parameter(Mandatory=$true, Position=1)]
        [string]$arg2
    )
    $XL = new-object -comobject Excel.application
    $XL.visible=$false
    $XL.displayalerts=$false
    $XL.workbooks.open("$arg1").SaveAs("$arg2",51)
    $XL.quit()
    #
    $XL2=new-object -comobject Excel.application
    $XL2.visible=$false
    $XL2.displayalerts=$false
    $WB=$XL2.workbooks.open("$arg2")
    $ws1=$wb.worksheets.item(1)
    $ws1.activate()
    #
    # Find the column count, to define our working-range.
    #
    $findrange=$ws1.usedrange.cells
    $colcount=$findrange.columns.count
    $workrange=$ws1.range($ws1.cells.item(1, 1), $ws1.cells.item(1, $colcount))
    #
    # Adjust the first row into a Header type Row
    #
    $workrange.font.bold=$true
    $workrange.interior.colorindex=15
    #
    # Set autofilter for all columns, and then autofit all columns.
    #
    $xl2.selection.autofilter() | out-null
    [void]$ws1.cells.entirecolumn.autofit()
    #
    # Save changes and close out.
    #
    $wb.saveas("$arg2")
    $wb.close()
    $XL2.quit()
}

*********************************end script********************

Use case:

$input="c:\testfolder\testfile.csv"
$output="c:\testfolder\convertedreport.csv"

CSVtoXLSX $input $output

Note:

The default sheet name given to the spreadsheet created will be the name of the original CSV file.

Random Notes:

I have for many years now, leveraged a VBS script to perform the same tasks I wrote this powershell function for. It still works wonderfully, I just wanted to see if I could do this conversion within powershell itself vs calling a seperate script.

There may be additional edits to this one adding features going forward, but the base code as it is solid and meant to be slapped into any existing powershell script. 


Thursday, February 20, 2020

Powershell: reporting on simple ldap DC connections

Every windows admin should be aware of what's coming March 2020:

https://support.microsoft.com/en-us/help/4520412/2020-ldap-channel-binding-and-ldap-signing-requirement-for-windows

The general recommendation at this point is to make this registry key adjustment to all your domain controllers:

# Enable Simple LDAP Bind Logging

Reg Add HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics /v "16 LDAP Interface Events" /t REG_DWORD /d 2

Once this has been done, you can monitor the event log on your DCs for event ID 2889 under the directory service log . . or you can run my script to check all your servers, and create a single report of all connections over the last 24 hours.

My script is based off the nice work by "Russell Tomkins" from Microsoft, his version available here:

https://github.com/russelltomkins/active-directory

The differences between our versions, his checks a single dc, mine checks the domain gets a list of DC's to check, then creates a report of all connections across them all.

The only parts to edit, are the lines for where to find the OU for he domain controllers, enter your domain name. And the path for the output CSV needs to exist as well.

hope it helps

**********start script***************

import-module activedirectory
cls
echo " "
echo " "
#
# Create shell arrays for holding the 2 needed data sets.
#
$Comps=@()
$Data=@()
#
# Gather list of Domain controllers
#
$Comps=get-adcomputer -filter * -searchbase "OU=Domain Controllers,DC=YOURDOMAINNAMEGOESHERE!!!,DC=com" | Sort Name
$compstocheck=$comps.count
#
# Gather data from each server's event logs, pull into single array.
#
echo " "
write-host "I found $compstocheck domain controllers, and will start checking their event data one by one" -foregroundcolor green
echo " "
ForEach ($DC in $Comps)
    {
        $dcname=$DC.name
        echo " "
        write-host "Pulling events from $dcname" -foregroundcolor Yellow
        echo " "
        $hours=24
        $Events=get-winevent -computername $dcname -filterhashtable @{Logname='Directory Service';Id=2889; StartTime=(get-date).AddHours("-$hours")} -ea silentlycontinue
        write-host "Processing events from $dcname" -foregroundcolor Cyan
        echo " "
        ForEach ($Event in $Events)
            {
$Etime=$Event.Timecreated
                $eventXML = [xml]$Event.ToXml()
                $Client = ($eventXML.event.EventData.Data[0])
                $IPAddress = $Client.SubString(0,$Client.LastIndexOf(":"))
                $Port = $Client.SubString($Client.LastIndexOf(":")+1)
                $User = $eventXML.event.EventData.Data[1]
                Switch ($eventXML.event.EventData.Data[2])
{
                        0 {$BindType = "Unsigned"}
                        1 {$BindType = "Simple"}
                    }
                $Row="" | select DCname,IPAddress,Port,User,BindType,TimeCreated
                $Row.DCname=$dcname
                $Row.IPAddress=$IPAddress
                $Row.Port=$Port
                $Row.User=$User
                $Row.BindType=$BindType
                $Row.TimeCreated=$ETime
                #
# Add the found event data to the master array
                #
                $Data +=$Row
            }
        write-host "Completed processing all related events for $DCname, moving on" -foregroundcolor Green
        echo " "
        }
#
#
write-host "Generating report" -foregroundcolor Green
echo " "
$Reportcsv="C:\SimpLdap\SimpleLdapReport.csv"
#
$Data | export-csv "$Reportcsv" -notypeinformation
#
*************End Script***********