Powershell – Windows firewall rules with ports

Every couple of months, I need to check Windows firewall on some secure/crucial Windows servers. I needed a automatic report that I can go through quickly. I used powershell, which goes through firewall rules, and in the end it creates an simple HTML report. Parts of code were used from Spiceworks Community

$ExportReport = "C:\Temp"
$Rules=(New-object -ComObject HNetCfg.FWPolicy2).rules|Where-Object {$_.enabled} |Sort-Object -Property direction,name |foreach-object{ [PSCustomObject] @{
FWName = $_.name
FWDescription= $_.description
FWApplicationName = $_.ApplicationName
FWServiceName = $_.ServiceName
FWProtocol = switch($_.Protocol)  { #https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
                                    256 {'Any'}
                                    58 {'IPv6-ICMP'}
                                    41 {'IPv6'}
                                    17 {'UDP'}
                                    6 {'TCP'}
                                    2 {'IGMP'}
                                    1 {'ICMP'}
                                    default {$_.Protocol}
                                    }
FWLocalPorts = $_.LocalPorts
FWRemotePorts =  $_.RemotePorts
FWLocalAddress = $_.LocalAddresses
FWRemoteAddress =  $_.RemoteAddresses
FWIcmpType= $_.ICMPType
FWDirection = switch($_.Direction) {
                                    1 {'Inbound'}
                                    2 {'Outbound'}
                                   }
FWAction = switch($_.Action)
                                    {
                                    1 {'Allow'}
                                    2 {'Deny'}

}
 }
 }
 
  $Header = @"
<style>
BODY{background-color:white;}
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH{border-width: 1px;padding: 5px;border-style: solid;border-color: black;foreground-color: black;background-color: LightBlue}
TD{border-width: 1px;padding: 5px;border-style: solid;border-color: black;foreground-color: black;background-color: white}
.green{background-color:#d5f2d5}
.blue{background-color:#277ece}
.red{background-color:#ff0004}
</style>
"@
 $PreContentHTML = "<hr>
                    <H3>Firewall Rules $env:COMPUTERNAME</H3>" 

$Rules|ConvertTo-HTML -head $Header -PreContent $PreContentHTML | Out-File "$ExportReport\$env:COMPUTERNAME.html"

In the end, I could read this report quickly and check/uncheck needed firewall rules.

Good Luck

Powershell and Lotus Notes pt3

Continuing on couple of my previos Lotus Notes and Powershell (pt1,pt2) posts..


Our Lotus Notes isn’t connected to AD, so everything must be done separately from AD. Users, groups, ACL, and so on. Couple of days ago, I had an request that one mail group in Lotus must be identical to one AD group. So, this request could bring me a lot of manual work.
Since I already have a script which can manipulate with users in LN, why wouldn’t I try to automatize the process of comparing the groups and populate LN with users from AD.

Lets start with runing the powershell in 32bit mode

#open powershell in 32bit mode
#Start-Process $Env:WINDIR\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
#or ISE
#Start-Process $Env:WINDIR\SysWOW64\WindowsPowerShell\v1.0\powershell_ise.exe
if([Environment]::Is64BitProcess -eq $true)
                    {
                    write-output "64bit NO GO" 
                    BREAK
                    } 
            else {
                        write-output "32bit OK"
                        } #because you have a 64-bit PowerShell

Declare some variables and connect to Lotus Server. I needed unconditional transfer from AD group to LN group, so the easiest way was to delete/empty the LN group and then populate it.

$strUserView = '$VIMPeople' #Group name for list of People
$strGroupView = '$VIMGroups'#Group name for list of Groups
$DomServer = "SERVER/LN"  
$DomDBPath = "names.nsf" #mailbox that contains users, groups.. etc..
$pwd4NotesDB = "Passw0rd"
$AdGroup = "AD_Group1"
$LNGroup = "LN_MailGroup1"



$DomSession = New-Object -ComObject Lotus.NotesSession #Use LN COM class
$DomSession.Initialize($pwd4NotesDB) #This is when Lotus asks for your password when you open it
$DomDatabase = $DomSession.GetDatabase($DomServer,$DomDBPath) #Initialize Database
                      
$DomGroupView  = $DomDatabase.GetView($strGroupView)
$DomGrp = $DomGroupView.GetDocumentByKey("$LNGroup") #Get group from Group List

#Now we save members to Array and prepare MaxArry to handle For loop
$userGrp = $DomGrp.GetFirstItem("members") #For text Append
$Array = @($userGrp.Values) #GetValues and save to array

If ($Array -ne $nul) #If any members, empty the LN group
    {
                            Write-Output 'Delete members'
                            $Array=""
                            $DomGrp.ReplaceItemValue("Members",$Array)
                            $DomGrp.Save('False','True')

    }

So the next thing is to get users from AD group. This is quite strightforward.

#region Domain Users
####DOMAIN GROUP MEMBERS
 $users = Get-Adgroupmember $AdGroup |Get-ADuser -Properties Name,mail |select Name,mail
 $returnObj = @()
                            
foreach ($user in $users)
    {
        $EndUser = ($user.name).Replace('Š','S').Replace('š','s').Replace('Č','C').Replace('č','c').Replace('ć','c').Replace('Ć','C').Replace('Ž','Z').Replace('ž','z').Replace('Đ','D').Replace('đ','d') #replace diacritic characters
        $EndUser = "$EndUser/LN"
        
        $obj = New-Object psobject -Property @{Name =$EndUser
                                        Mail = $user.mail}
        $returnObj += $obj | select Name,mail
    }

$UsersFromAD= $returnObj |Select-Object Name,Mail |Sort-Object Name

#endregion

Now we must get all the users in LN and compare mail addresses. Well this was a problem, because some users have two (some more) last names. And somewhere those users have minus between them, somewhere there is just space.

#region Lotus

$DomUserView  = $DomDatabase.GetView($strUserView) #Initialize View
$Counterf = $DomUserView.GetFirstDocument()
$returnObj1 = @()
While ($CounterF -ne $nul) {

            $DomNexDocument = $DomUserView.GetNextDocument($CounterF)
            $DomeLoopAddress = $CounterF.GetItemValue("InternetAddress") #GetSubject
            $DomeLoopFirstName = $CounterF.GetItemValue("FirstName")
            $DomeLoopFLastName = $CounterF.GetItemValue("LastName")
            $obj1 = New-Object psobject -Property @{FirstName =$DomeLoopFirstName
                                                    LastName = $DomeLoopFLastName
                                                    Mail = $DomeLoopAddress}
            $returnObj1 += $obj1 | select FirstName,LastName,mail
            $CounterF = $DomNexDocument 
}
$UsersfromLotus = $returnObj1 |Select-Object FirstName,LastName,Mail 

#endregion Lotus
$Users2Group = $UsersfromLotus |?{$UsersFromAD.mail -contains $_.mail} #get users from lotus where in ADgroup
$Users2GroupTEst = $UsersFromAD |?{$UsersfromLotus.mail -notcontains $_.mail} #get users from ADgroup where cannot find in Lotus
 IF ($Users2GroupTest)
    {
    Write-output "User $Users2GroupTEst not transfered to group"
    #Do something if user not found /send mail / save Event
    }

foreach ($user2Group in $Users2Group)
{
#combine FirstName and LastName from Lotus, because it can be different from AD user FirstName and LasName
$FirstName = $user2group.FirstName
$LastName = $user2group.LastName
$UserCombine = "$FirstName $LastName/LN"
                    $userGrp.AppendToTextList($UserCombine) #Add users to end of members list
                    $DomGrp.Save('False','True') #Save Group
            #this works finaly :)
            }

This is besically copy/paste of users from AD groups to Lotus Groups. Now you can put this script into Task scheduler or some other automatization software, and keep the groups in sync.

Good luck

Powershell and Lotus Notes pt2

To continue my journey (PS and LN pt1) in PS scripting on Lotus Notes, I wanted to see if it is possible to manipulate groups members in LN. Well, it is possible, and I will show you how I did it.

As you remeber from my last post, If you want to connect to Lotus Notes via PS, you must start powershell or PS ISE in 32bit mode.

#open powershell in 32bit mode
#Start-Process $Env:WINDIR\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
#or ISE
#Start-Process $Env:WINDIR\SysWOW64\WindowsPowerShell\v1.0\powershell_ise.exe
if([Environment]::Is64BitProcess -eq $true)
                    {
                    write-output "64bit NO GO" 
                    BREAK
                    } 
            else {
                        write-output "32bit OK"
                        } #because you have a 64-bit PowerShell

We are going to try this on a test group called #LN_TEST_GRP and the user we are going to add/remove from this group is CN=User TEST/O=LNDS

#Parameters
$strUserView = '$VIMGroups'  #System name for groups view in names.nsf
$DomServer = "SERVER/LN" 
$DomDBPath = "names.nsf" #mailbox that contains users, groups.. etc..
$pwd4NotesDB = "Passw0rd" 

$User = "CN=User TEST/O=LNDS"
$LNGroup = "#LN_TEST_GRP"
$Insert = 0 #1 for insert user
$Delete = 0 #1 for delete user
$Array = "" #Set Array to empty

#This part is for testing insert/delete - manually set values
$delete=0
$Insert=0
#

$DomSession = New-Object -ComObject Lotus.NotesSession #Use LN COM class
$DomSession.Initialize($pwd4NotesDB) #This is when Lotus asks for your password when you open it
$DomDatabase = $DomSession.GetDatabase($DomServer,$DomDBPath) #Initialize Database
$DomGroupView  = $DomDatabase.GetView($strGroupView) #Initialize View

$DomGrp = $DomGroupView.GetDocumentByKey("$LNGroup") #Get group from Group List
#Now we save members to Array and prepare MaxArry to handle For loop
$userGrp = $DomGrp.GetFirstItem("members") #For text Append
$Array = @($userGrp.Values) #GetValues and save to array
$MaxArray = $Array | measure -Maximum #GetMaxOf Array
$MaxArray = $MaxArray.Count #GetMaxOf Array

Now, when we got this sorted, the next step is manipulating group members. First we will add the user, then we are going to remove it from group.

The process of insert is very straightforward, If user is not on the member list, add the user to the end of that same list.

#INSERT USER INTO GROUP DOCUMENT
IF ($Insert -eq 1) # IF INSERT IS 1 
{
        IF (($userGrp.values -contains $User))
            {
                "******************User Exists - EXIT****************"
            }
        else
            {
                "******************User NotExist - INS****************"
                IF (($User -ne $nul) -and ($LNGroup -ne $nul))
                    {
                    $userGrp.AppendToTextList($User) #Add user to end of members list
                    $DomGrp.Save('False','True') #Save Group
                    }
            }
}

The process of deleting user from members list is little more complicated than insert. We input members to array, find user that needs to be deleted and replace the user with “”, then we cleanup the array, and finally we replace members value in LN group document with that new array.

#REMOVE USER FROM GROUP DOCUMENT
IF ($Delete-eq 1) # IF DELETE IS 1 
{    
        
        IF (($userGrp.values -contains $User))
            {
                "*******************User exists - DEL****************"
               IF (($User -ne $nul) -and ($LNGroup -ne $nul))
                    {

                            for ($i=0; $i -lt $MaxArray; $i++) #FOR Loop
                            {
                                IF ($array[$i] -eq $User) #IF user is in the list
                                {
                                $array[$i] = "" #Set "" for that user
                                $Array = $Array | Where { -not [string]::IsNullOrWhiteSpace($_) }     #Clean Array of blank spaces
                                }
                            }
                            #$Array
                            $Array=$Array.Trim() #Array Trim
                            $DomGrp.ReplaceItemValue("Members",$Array) #Replace Members list with our new array without the specific user
                            $DomGrp.Save('False','True') #Save Group document
                    } 
            }
        else
            {
                
                   "*******************User NotExists - EXIT****************"
   
            }
  }

So, this should cover the basics in adding and removing users from Lotus Notes.

Good Luck

Powershell and Lotus Notes

As you might know, Powershell works best with other Microsoft products, like MS Exchange.

Now what happens when you want to connect PS to some non Microsoft products? In my case that was Lotus Notes. The collaboration giant. As you probably know, Lotus has its own LotusScritp language, with whom you may create Lotus databases, agents, users, etc… With it you can do almost anything in Lotus.
Since I like to test and experiment with Powershell, and one of my projects was Powershell script and Exchange, Self-service user portal, I decided to play with Powershell and Lotus Notes. And I must say, I works.

First of all, If you want to connect to Lotus Notes via PS, you must start powershell or PS ISE in 32bit mode.

#open powershell in 32bit mode
#Start-Process $Env:WINDIR\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
#or ISE
#Start-Process $Env:WINDIR\SysWOW64\WindowsPowerShell\v1.0\powershell_ise.exe
if([Environment]::Is64BitProcess -eq $true)
                    {
                    write-output "64bit NO GO" 
                    BREAK
                    } 
            else {
                        write-output "32bit OK"
                        } #because you have a 64-bit PowerShell

Once you open the PS or ISE (I’m more of ISE or Visual Code person), you can start connecting to Lotus Notes.

One of my tasks, was to extract an HTML attachment which was sent everyday by our backup system. But with this code, will go through all mail documents in Inbox, and for those that have attachment, it will create a folder for every sender and create date subfolder with attachments in it.

#Parameters
$strUserView = '$Inbox'  
$DomServer = "SERVER/LN" 
$DomDBPath = "mail\user.nsf" 
$pwd4NotesDB = "Passw0rd" 
$ipPath2Export = "C:\Temp"

$DomSession = New-Object -ComObject Lotus.NotesSession #Use LN COM class
$DomSession.Initialize($pwd4NotesDB) #This is when Lotus asks for your password when you open it
$DomDatabase = $DomSession.GetDatabase($DomServer,$DomDBPath) #Initialize Database
$DomView  = $DomDatabase.GetView($strUserView) #Initialize View

Since the script has to go through all the mail, we need the loop.

$Counterf = $DomView.GetFirstDocument() #Define first document in view
While ($CounterF -ne $nul) {

$DomNexDocument = $DomView.GetNextDocument($CounterF) #Define Next doc

#Define some fields
$DomeLoopSubject = $CounterF.GetItemValue("Subject") #GetSubject
$DomeLoopFrom = $CounterF.GetItemValue("From") #GetFrom
$DomeLoopDate = $Counterf.GetItemValue("DeliveredDate")
$DomeLoopDate = '{0:yyyyMMdd}' -f $DomeLoopDate #GetDateandFormat

#for folder name we need to clean FROM
$DomeLoopFrom=$DomeLoopFrom.Replace("CN=","")
$DomeLoopFrom=$DomeLoopFrom.Replace("/O=LN","")
$DomeLoopFrom=$DomeLoopFrom.Replace("<","")
$DomeLoopFrom=$DomeLoopFrom.Replace(">","")
#$DomeLoopFrom=$DomeLoopFrom.Replace("@","")
$DomeLoopFrom=$DomeLoopFrom.Replace("\","")
$DomeLoopFrom=$DomeLoopFrom.Replace("/","")
$DomeLoopFrom=$DomeLoopFrom.Replace("`"","")

IF ($Counterf.HasEmbedded -eq "True") #IF attachment exists
    {
      $AttachItem = $Counterf.GetFirstItem("Body") #Get all attachments     
        
       Foreach($A in $attachItem.EmbeddedObjects)
        {
            $DomAttachSavePath = "$ipPath2Export"
            $DOmAttachSavePath = $DOmAttachSavePath+$DomeLoopFrom 
            $FILENAME=$A.Name
            $DomAttachSavePath=$DomAttachSavePath+"\"+$DomeLoopDate   
            Write-Output "Possible path  $DomAttachSavePath"
            New-Item -ItemType Directory -Force -Path $DomAttachSavePath >$null
            $Extractto = $DomAttachSavePath+"\"+$FILENAME       
            $A.EXTRACTFILE($Extractto) 
      }

    }
$CounterF = $DomNexDocument #Raise counter
}

So, this is how I managed to export all attachments from my Inbox in Lotus Notes.

Good Luck

DNS management Windows 10 1709

Recentley I discovered that DNS management is not installed when installing RSAT (WindowsTH-RSAT_WS_1709-x64) to Windows 10 1709 (Fall Creators Update).

After trying to install RSAT for Windows Server 2016, it was still missing. So I turned to Technet and I found a  article  (here).

The thing is that you have to download the following files and copy them to your system32 folder. It would be the best to copy it from your local Windows 2016 server.

%windir%\system32\dnsmgmt.msc
%windir%\system32\dnsmgr.dll
%windir%\system32\en-us\dnsmgmt.msc
%windir%\system32\en-us\DNSmgr.dll.mui

After that you must run CMD as an Administrator and run:
regsvr32 c:\windows\system32\dnsmgr.dll

And now you can run %windir%\system32\dnsmgmt.msc to open the DNS management console.

Good Luck

WinRM problems

Couple of days ago, I installed new version of Project Honolulu. I added few serves, but one of them reported error connecting.

Error reported WinRM connection failed.

So I tested it with PowerShell

Test-WSMan –ComputerName SERVER01.corp.loc

And yes, there was an error:
Test-WSMan : <f:WSManFault xmlns:f=”http://schemas.microsoft.com/wbem/wsman/1/wsmanfault” Code=”2150858770″ Machine=”SOURCEPC.corp.loc”><f:Message>The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: “winrm quickconfig”. </f:Message></f:WSManFault>At line:1 char:1+ Test-WSMan –ComputerName SERVER01.corp.loc+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (aasv029.uniqa.hr:String) [Test-WSMan], InvalidOperationException
+ FullyQualifiedErrorId : WsManError,Microsoft.WSMan.Management.TestWSManCommand

So the first step wast to run the command “winrm quickconfig” on the server, and restarted the service.
This didn’t help, so I had to figure something out.

After couple of hours of testing and configuring, I stumbled upon the Technet forum (here).
WinRM was listening on port 5985, but only on loopback (127.0.0.1) interface.

netsh http show iplisten
IP addresses present in the IP listen list:
——————————————-
127.0.0.1

After I deleted the problematic listener and restarted the service, WinRM started to work, and I finally got to play with Project Honolulu.

netsh http delete iplisten 127.0.0.1
Restart-Service winrm
Test-WSMan -ComputerName SERVER01.corp.loc

wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 3.0

Good Luck

Active Directory Logon Script

Hi,
for some time now we used batch script to log user logon to theirs domain computers. What we collected via this script was something like this:

Mon 02.01.2017., 7:55:06,64,user1,AD-PC1,Windows 7 or Server 2008R2,32 Bit
Mon 02.01.2017., 7:55:42,90,user2,AD-PC2,Windows 7 or Server 2008R2,64 Bit
Mon 02.01.2017., 7:55:46,51,user3,AD-PC3,Windows 7 or Server 2008R2,32 Bit
Mon 02.01.2017., 7:55:50,94,user4,AD-PC4,Windows 7 or Server 2008R2,64 Bit

But now (well not now, but some time ago) Powershell started to improve IT life.
So logon script that I use now on my domain is as follows:

$ipV4 = Test-Connection -ComputerName $env:ComputerName -Count 1  | Select -ExpandProperty IPV4Address

$Date = Get-Date -format “dd.MM.yyyy HH:mm”

$OutputFile = ‘UNC Path\logon.txt’

$TotalMemory = (Get-WMIObject -class Win32_PhysicalMemory |Measure-Object -Property capacity -Sum | % {[Math]::Round(($_.sum / 1GB),2)})
$String = $Date +”, “
$String += $env:UserName +”, “
$string += $env:ComputerName  +”, “
$string += $ipV4.IPAddressToString +”, “
$string += (Get-WmiObject -class Win32_OperatingSystem).Caption +”, “
$string += (Get-WmiObject -class Win32_OperatingSystem).OSArchitecture +”, “
$string += (Get-WmiObject CIM_ComputerSystem).Model+ ” (” + (Get-WmiObject CIM_ComputerSystem).SystemFamily + “) sn:” +(Get-WmiObject Win32_Bios).Serialnumber +”, “
$String += [string]$TotalMemory +”GB RAM, “
$String += “IE: ” + (Get-ItemProperty ‘HKLM:\Software\Microsoft\Internet Explorer’).SvcVersion
$string | Out-File $OutputFile –Append

And now we get full information who logged on, at what time, from what IP address and from what particular PC
Now collection looks like this:
29.09.2017 18:21, user1, AD-PC1, 10.10.10.1, Microsoft Windows 7 Professional , 32-bit, Model1 (Lenovo X230) sn:1111111, 4GB RAM, IE: 11.0.9600.18762
29.09.2017 18:36, user2, AD-PC2, 10.10.10.2, Microsoft Windows 7 Professional , 32-bit, Model2 (HP370 AIO) sn:11111112, 4GB RAM, IE: 11.0.9600.18762
29.09.2017 18:39, user1, AD-PC3, 10.10.10.3, Microsoft Windows 7 Enterprise , 64-bit, Model3 (XXXXXX) sn:1123141, 4GB RAM, IE: 11.0.9600.18762
I suggest you open the txt file with Notepad++ because it does not lock file for further write.

Good Luck!

Managing DNS in Workgroup

So,
we are migrating our external DNS servers to another IP pool. SO I had to create a DNS server (later two), which will be on new IP pool, so we can remove the old ones.

I used Microsoft Windows Server 2016 Core version for this. No excessive updates, GUIs or problems.
But, since it is Core  edition and it is not domain integrated, I had to manage the server remotely.

If you are going to manage it from domain computer, I strongly recommend that you create a DNS record on AD integrated DNS for this server.

I needed to enable Remote Administration through Windows Firewall on the new server:

Netsh advfirewall firewall set rule group=”remote administration” new enable=yes

Next, on the client side, you must create Windows Credentials via GUIimage

image

Or via command line:

cmdkey /add:Servername /user:Servername\administrator /pass:password

And in the end open DNS manager, and connect to the server:

image

Good Luck

Hide DNS Version

Some time ago, I’ve setup internal (AD based) DNS and external DNS for our domain. Now, when you do domain checkup with BIND tools, you will usualy get DNS version. For my external DNS it reported it was Windows server DNS. Now, for that problem (security issues), I found a solution on: http://www.admin-enclave.com/en/solutions/windows/146-hide-microsoft-dns-software-version.html
I is pretty simple, over CMD or over REGEDIT;
dnscmd /config /EnableVersionQuery 0
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\DNS\Parameters\EnableVersionQuery to 0

 

More on the subject:

https://msdn.microsoft.com/en-us/library/cc422472.aspx

 

Good Luck

Windows 10 start menu search problem

Hi,

when Windows 10 came out, I bravely installed it on my business notebook. It works great, except Start menu search. Everything I searched returned blank. So I got couple of days to check what was going on.
I tried repairing Windows with SFC, I tried turning off Cortana, tamper with registry.. but nothing worked.
Then I suspected the GPO. So, I tested one by one, and finally I got to one where we had all our Internet Explorer settings.
After couple hours of trial and error, I got to conclusion that this two settings enabled Windows 10 start menu search:

Allow Website caches and database must be turned on, and I set it up to 50MB (default is 10)

image

And if pop-up blocker is turned on, change it’s setting to Low: allow pop-ups from secure sites.

image

So this helped for me.

Good Luck