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 = @"
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}
 $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" 
            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'


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

#region Domain Users
 $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


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