Checkpoint.psm1

#requires -Version 3.0 -Modules core, Posh-SSH


#region System commands


Function Get-CheckPointActiveShell
{
    Param
    (
        [Parameter(Mandatory=$true, HelpMessage='IP or hostname of the firewall')]
        [String] $Firewall,
        
        [Parameter(Mandatory=$true, HelpMessage='Creds for user with clish shell')]
        
        [PSCredential] [System.Management.Automation.Credential()] $Credential
    )
    
    $strCommand = 'echo $SHELL'
    $strFailed = 'CLINFR0329'
    
    # Create an SSH session to the firewall
    $objSession = New-SSHSession -Credential $Credential -ComputerName $Firewall
    
    
    $retVal = Invoke-SSHCommand -SessionId $objSession.SessionId -Command $strCommand
    
    If ($retVal.Output -match $strFailed)
    {
        Return 'CliSH'
    }
    Else
    {
        $retVal.Output
    }
    
    # Clean up
    $null = Remove-SSHSession -SessionId $($objSession.SessionId) 
}


Function Get-CheckpointVpnActiveUser
{ # Get the count or details of all users connected via VPN
    # Get all the connected users, and their data [UserName, UserDN, PeerLast, Expires]
    # fw tab -t userc_users -f | sed 's/;/\n/g'
    
    # Get a count of active users
    # "fw tab -t userc_users -s |grep userc_users |sed 's/ \+/ /g' |cut -d' ' -f4"
    
    Param
    (
        [Parameter(Mandatory=$true, Position=0,
        HelpMessage='Firewall')]
        [Alias('Firewall')]
        [String] $Server,
        
        [Parameter(Mandatory=$true, Position=1,
        HelpMessage='Credentials to connect to your firewall')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential
    )
    
    Begin
    {
        # Debugging for scripts
        $Script:boolDebug = $PSBoundParameters.Debug.IsPresent
        
        # List of required modules for this function
        $arrayModulesNeeded = (
            'Posh-SSH','core'
        )
        
        # Verify and load required modules
        $ErrorActionPreference = 'Stop'
        Test-ModuleLoaded -RequiredModules $arrayModulesNeeded -Quiet
    }
    
    Process 
    {
        # Get active users
        [String] $strCommand = 'fw tab -t userc_users -f'
    
        # Connection
        $objSessionCheckpoint = New-SSHSession -ComputerName $Server -Credential $Credential -AcceptKey -ConnectionTimeout 90
        $sshStream = New-SSHShellStream -SessionID $($objSessionCheckpoint.SessionID)
        
        $rawOutput = @()
    
    
        # Execute commands on the server via ssh
        $null = $sshStream.Read() # Clear the default messages from the buffer.
        $SshStream.WriteLine($strCommand) 
        $boolDataReceived = $false
        
        :waiter While ($true)
        {
            $streamOut = $sshStream.Read() 
            
            If ($boolDataReceived -eq $true -and $streamOut.Length -eq 0)
            {
                break waiter
            }
            
            If ($streamOut.Length -gt 0) 
            {
                $rawOutput += $streamOut
                $streamOut = $null 
                $boolDataReceived = $true # Watch until we do not receive data anymore
            }

            Start-Sleep -Seconds 2 # fw is sloooow.
        }
    
        # Data
        $objOfHolding = @()
     
        Foreach ($Thing in $( $rawOutput.Split("`n") | Select-String -Pattern ' :(+);' -SimpleMatch -AllMatches) ) 
        {
            $objBuilder = New-Object -TypeName PSObject

            Foreach ($line in $Thing.ToString().Split(';'))
            {
                $line = $line.Trim("^,")

                If ($line -notmatch "^$|^\s")
                {
                    # Temp variables
                    $tmpName = $null
                    $tmpName = $line.Split(':')[0]
                    
                    If ($tmpName.Trim() -eq 'ConnectTime')
                    {
                        $tmpName = $tmpName + '_UTC'
                        $tmpVal = $null
                        $tmpVal = $line.Split(':')[1]
                        
                        # Object stored in CTIME/Unix time format
                        $epoch = get-date '1/1/1970'
                        $tmpVal = $epoch.AddSeconds($tmpVal)
                    }
                    
                    Else
                    {
                        $tmpVal = $null
                        $tmpVal = $line.Split(':')[1]
                    }
                
                    Invoke-DebugIt -Console -Message 'Name' -Value $tmpName
                    Invoke-DebugIt -Console -Message 'Value' -Value $tmpVal
                
                    $objBuilder | 
                    Add-Member -MemberType NoteProperty -Name $tmpName -Value $tmpVal
                }
            }
        
            $objOfHolding += $objBuilder
        }
    
        If (!($objOfHolding.Count -gt 0)) 
        {
            Write-Host "`n"
            Write-Host 'No data returned. Try increasing the timeout. You may have a slow firewall :(' -ForegroundColor Red
            Write-Host "`n"
        }
        
        Else
        {
            $objOfHolding
        }
    }
    
    End
    {
        $null = Remove-SSHSession -SessionId $($objSessionCheckpoint.SessionID) 
    }
}


Function Add-CheckpointSamDatabaseEntry
{
    <#
            .Synopsis
            Block an IP on your Checkpoint firewall
 
            .DESCRIPTION
            Uses the destination IP address to block all traffic to that host
 
            .EXAMPLE
            Add-CheckpointSamDatabaseEntry firewall1 forever john
 
            .EXAMPLE
            Add-CheckpointSamDatabaseEntry -Server firewall1 -BlockTime Hour -Credential $myCreds
    #>


    <#
            Version 0.0
            - Day one!
 
            TODO: Add more functionality for editing the SAM database
    #>


    [CmdLetBinding()]
    Param
    (   <#
                [Parameter(Mandatory=$true, Position=0,
                HelpMessage='Select the type of action you wish to take.')]
                [ValidateSet('Block','CSV','Screen','GridView')]
                [String] $Action,
        #>
                         # Currently only blocking
        
        [Parameter(Mandatory=$true, Position=0,
        HelpMessage='Firewall')]
        [String] $Server,
        
        [Parameter(Mandatory=$true, Position=0,
        HelpMessage='Destination IP we want to block')]
        [Alias('host')]
        [String] $ThreatActor,
        
        [Parameter(Position=1)]
        [ValidateSet('10Minutes','Hour','Day','Week','Forever')]
        [String] $BlockTime = 'Hour',
        
        [Parameter(Mandatory=$true, Position=2,
        HelpMessage='Credentials to connect to your firewall')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential
    )
    
    Begin
    {
        # Debugging for scripts
        $Script:boolDebug = $PSBoundParameters.Debug.IsPresent
        
        # List of required modules for this function
        $arrayModulesNeeded = (
            'Posh-SSH','core'
        )
        
        # Verify and load required modules
        Test-ModuleLoaded -RequiredModules $arrayModulesNeeded -Quiet
    }
    
    Process
    {
        # Variables
        $dicTime = @{
            '10Minutes' = 600
            'Hour' = 3600
            'Day' = 86400
            'Week' = 604800
        }
        [String] $strCommand = 'fw sam '
        
        If (!($BlockTime -eq 'Forever'))
        {
            $strCommand += '-t {0} ' -f $dicTime[$BlockTime]
        }
        
        $strCommand += '-I dst {0}' -f $ThreatActor

        $objSessionCheckpoint = New-SSHSession -ComputerName $Server -Credential $Credential -AcceptKey -ConnectionTimeout 90
        $sshStream = New-SSHShellStream -SessionID $($objSessionCheckpoint.SessionID)
        $rawOutput = ''
        
        
        $SshStream.WriteLine($strCommand) 
        Start-Sleep -Seconds 1
        $rawOutput = $sshStream.Read()
    }
    
    End
    {
        $null = Remove-SSHSession -SessionId $($objSessionCheckpoint.SessionID)
    }
}


Function Set-CheckPointStaticRoute
{
    [CmdLetBinding()]
    Param
    (
        [Parameter(Mandatory=$true)]
        [IPAddress] $Network,
        
        [Parameter(Mandatory=$true)]
        [IPAddress] $Mask,
        
        [Parameter(Mandatory=$true)]
        [IPAddress] $Gateway,
        
        [ValidateSet('on','off')]
        [String] $State = 'on',
        
        [Parameter(Mandatory=$true, HelpMessage='IP or hostname of the firewall')]
        [String] $Firewall,
        
        [Parameter(Mandatory=$true, HelpMessage='Creds for user with clish shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential,
        
        [Switch] $Force
    )
    
    $strShell = Get-CheckPointActiveShell -Firewall $Firewall -Credential $Credential
    
    Try
    {
        $objAddr = IP-Calc -IPAddress $Network -Mask $Mask -WarningAction Stop -ErrorAction Stop
    }
    Catch
    {
        Throw
        Return
    }
    
    #[String] $strCidr = (Convert-SubnetMaskToCidr -SubnetMask $Mask).ToString()
    [String] $strCidr = $objAddr.PrefixLength.ToString()
    
    [String] $strCommand = 'set static-route {0}/{1} nexthop gateway address {2} {3}' -f `
    $Network.IPAddressToString,$strCidr,$Gateway.IPAddressToString,$State
    
    If ($strShell -eq 'CliSH')
    { 
        $objSession = New-SSHSession -Credential $Credential -ComputerName $Firewall

        $retVal = Invoke-SSHCommand -SessionId $objSession.SessionId -Command $strCommand
    
        $retVal
    
        # Clean up
        $null = Remove-SSHSession -SessionId $($objSession.SessionId) 
    }
    Else
    {
        Write-Error -Message "`nThis command requires SuperShell (CliSH) as the default. You're using $strShell `n"
        Return
    }
}


New-Alias -Name Get-CheckpointVpnActiveUsers -Value Get-CheckpointVpnActiveUser -ErrorAction SilentlyContinue -WarningAction SilentlyContinue


#endregion


#region Bulk import commands


Function New-CheckPointImportFile 
{ 
    # Build a clean import list for Checkpoint network objects from a CSV file
    <#
            CSV Headers
            Group,CIDR,IP,Netmask,Type,Site,Name,Color,Comment
    #>

    
    Param
    (
        [String] $InputFile = ".\nodes.csv",
        
        [String] $OutputFile = ".\$(Get-Date -UFormat '%Y%m%d-%H%M%S')-dbedit-import.txt",
        
        [Parameter(Mandatory = $True, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
        
        [Parameter(Mandatory = $True, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential
    )
    # Note: The "-" (dash) sign is used in INSPECT code as a word separator, and any string that is in the form of: "<characters>-<reserved word>" cannot be used (e.g., the name "something-inbound"). *** in English... just use an underscore ("_") character.

    # Variables:
    [System.Collections.ArrayList] $arrayCollectionOutput = @()
    # Empty array for building temporary output.
    $boolShouldContinue = $true
    $boolDebug = $true

    # Private functions:
    function createNetworkObject ([String] $Name, [String] $Color, [String] $Comments, [String] $IP, [String] $Netmask, [String] $Group) { # Output code to create network object
        $arrayCollectionOutput.Add("create network $Name")
        $arrayCollectionOutput.Add("modify network_objects $Name ipaddr $IP")
        $arrayCollectionOutput.Add("modify network_objects $Name netmask $Netmask")
        $arrayCollectionOutput.Add("modify network_objects $Name color `"$Color`"")
        $arrayCollectionOutput.Add("modify network_objects $Name comments `"$Comments`"")
        #$arrayCollectionOutput.Add("update network_objects $Name")
        $arrayCollectionOutput.Add("addelement network_objects $Group `'`' network_objects:$Name")
        #$arrayCollectionOutput.Add("update network_objects $Group")
    }
    
    function createHostObject ([String] $Name, [String] $Color, [String] $Comments, [String] $IP, [String] $Group) { # Output code to create a host object
        $arrayCollectionOutput.Add("create host_plain $Name")
        $arrayCollectionOutput.Add("modify network_objects $Name ipaddr $IP")
        $arrayCollectionOutput.Add("modify network_objects $Name color `"$Color`"")
        $arrayCollectionOutput.Add("modify network_objects $Name comments `"$Comments`"")
        #$arrayCollectionOutput.Add("update network_objects $Name")
        $arrayCollectionOutput.Add("addelement network_objects $Group `'`' network_objects:$Name")
        #$arrayCollectionOutput.Add("update network_objects $Group")
    }
    
    function createGroupObject ([String] $Name, [String] $Color, [String] $Comments) { # Output code to create a group object
        $arrayCollectionOutput.Add("create network_object_group $Name")
        $arrayCollectionOutput.Add("modify network_objects $Name color `"$Color`"")
        #$arrayCollectionOutput.Add("update network_objects $Name")
    }
    
    
    if ($Firewall.length -gt 0) { # Check if we'll be comparing the our items against the current firewall configuration.
        # Make the credential parameter required.
        if ($Credential.UserName.Length -gt 0) { 
            $boolShouldContinue = $true
            $boolCheckFirewall = $true
            #If ($boolDebug -eq $true) {Write-Host "Firewall is set to $Firewall"}
        }else {
            # $boolShouldContinue = $false
        }
    }
    
    if ($boolShouldContinue = $true) {
        if ($boolCheckFirewall -eq $true) {
            # Get the list of objects from the firewall
            $ArrayCurrentFirewallObjects = Export-CheckPointNetworkConfig -Credential $Credential -Firewall $Firewall
            #If ($boolDebug -eq $true) {Write-Host "Boolean value for checking firewall is True"}
        }
        
        $objImportFile = Import-CSV $InputFile -Encoding ascii
        # Import the CSV file for getting the data
        #If ($boolDebug -eq $true) {Write-Host "Imported the CSV file"}
        
        foreach ($line in $objImportFile) { # Loop through the lines in the CSV, and create the output collection
            # Variables
            $strObjectName = $($line.Name).Trim()
            $strObjectIP = $($line.IP).Trim()
            $strObjectColor = $($line.Color).Trim()
            # dodgerblue3, olive drab, orchid, aquamarine, black
            $strObjectGroup = $($line.Group).Trim()
            $strObjectComment = $($line.Comments).Trim()
            $strObjectType = $($line.Type).Trim()
            # host_plain, network, network_object_group
            $strObjectMask = $($line.Netmask).Trim()
 
        
            # Figure out what kind of object we're working with and build the list.
            switch ($strObjectType) {
                host_plain { # Run the createHostObject function.
                    createHostObject -Name $strObjectName -Color $strObjectColor -Comments $strObjectComment -IP $strObjectIP -Group $strObjectGroup | Out-Null
                    break
                }  
                network { # Run the createNetworkObject function
                    createNetworkObject -Name $strObjectName -Color $strObjectColor -Comments $strObjectComment -IP $strObjectIP -Netmask $strObjectMask -Group $strObjectGroup | Out-Null
                    break
                } 
                network_object_group { # Run the createGroupObject function
                    createGroupObject -Name $strObjectName -Color $strObjectColor -Comments $strObjectComment | Out-Null
                    break
                }
            }
            
            
        } #If ($boolDebug -eq $true) {Write-Host "Finished creating all objects"}
        
        # Clean up the list, if we need to compare to existing firewall output.
        if ($boolCheckFirewall -eq $true) { # Compare and order objects. Create all groups first if they don't exist.
            
            # Build the list of groups from our array.
            $arrayGroupNames = $arrayCollectionOutput.Group |Sort-Object -Unique
            #If ($boolDebug -eq $true) {Write-Host "**** Unique group names ****"$arrayGroupNames}
                
            $arrayHostNames = $arrayCollectionOutput |Where-Object {$_.Type -eq 'plain_host'} | ForEach-Object {$_.Name}
            $arrayNetworkNames = $arrayCollectionOutput |Where-Object {$_.Type -eq 'network'} | ForEach-Object {$_.Name}
            
            # Build an array for cleaned list of items to create.
            [System.Collections.ArrayList] $arrayCleanedOutput = $arrayCollectionOutput
            # This will be our cleaned output file.
            [System.Collections.ArrayList] $arrayGroupsToCreate = @()
            
            # Remove any host or network objects that were found in the firewall output.
            foreach ($line in $ArrayCurrentFirewallObjects) { 
                foreach ($record in $($arrayCleanedOutput |Select-String "$line")) {
                    $arrayCleanedOutput.Remove($record.ToString())
                    
                    #If ($boolDebug -eq $true) {Write-Host "Removing: $record"}
                }
            }
            
            foreach ($Group in $arrayGroupNames) { # Check if the groups already exist
                # Add to the collection array if missing from firewall array.
                if ($ArrayCurrentFirewallObjects.Contains("$Group") -eq $false) {$arrayGroupsToCreate.Add("$Group")}
            }

            if ($arrayGroupsToCreate.Count -gt 0) { # Do we have any groups to create?
                foreach ($Group in $arrayGroupsToCreate) { # Lookup the object in the array, and pump this out to the proper function
                    $objTempGroup = $objImportFile |Where-Object {$_.Group -eq "$Group"} |Select-Object -First 1
                    $arrayCleanedOutput.Add("create network_object_group $Group")
                    $arrayCleanedOutput.Add("modify network_objects $Group color `"$($objTempGroup.Color)`"")
                    #$arrayCollectionOutput.Add("update network_objects $Group")
                }
            }
        }
        
        # Add the update command to the end of the script file.
        $arrayCollectionOutput.Add("update_all")
        
        # Create the output file if it doesn't exist.
        Invoke-Touch -Path $OutputFile | Out-Null
        
        if ($boolCheckFirewall -eq $true -and $arrayCleanedOutput.Count -gt 0) { # Output the cleaned file
            $CleanOutFile = "Cleaned-$(Get-ChildItem $OutputFile | ForEach-Object{$_.Name})"
            Invoke-Touch -Path $CleanOutFile | Out-Null
            $CleanOutFile = Get-ChildItem $CleanOutFile | ForEach-Object{$_.FullName}
            
            # Write the output to the cleaned file
            [System.IO.File]::WriteAllLines($CleanOutFile, ($arrayCleanedOutput))
            
            ConvertFrom-DosToUnix -FilePath $CleanOutFile
            # Convert to Unix line terminators.
        }
        
        # Get the full name of the file
        $Outputfile = Get-ChildItem $Outputfile |ForEach-Object{$_.FullName}
        # System.IO.File works from your home directory.
        
        # Output the collection to the output file
        [System.IO.File]::WriteAllLines($OutputFile, ($arrayCollectionOutput))

        # Convert the file to Unix format, as we'll be sending this file to the firewall for processing.
        ConvertFrom-DosToUnix -FilePath $OutputFile
        
        Write-Host "Your dbedit import has been created. Copy the file or its contents to your mgmt server and execute the following command"
        Write-Host " dbedit -continue_updating -f file_name -s localhost -u admin_account , you will then be prompted for the password. Enter it and your done"
    }
    else {
        Write-Host "Missing parameter. Check ur work, son!"
    }
}


Function Import-CheckPointBulkObject 
{ 
    # Checkpoint Firewall object import tool
    # Import a network objects file into the CheckPoint database. Provisioning just got easy son!!!

    Param 
    (
        [Parameter(Mandatory = $True, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential, 
        
        [Parameter(Mandatory = $True, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall, 
        
        [Parameter(Mandatory = $True, HelpMessage = 'Input file')]
        [String] $InputFile,
        
        [String] $RemotePath,
        
        [Int] $Port = 22
    )
    
    # Variables:
    if ($RemotePath.Length -lt 1) {$RemotePath = "/home/$($Credential.UserName.ToString())"}
    $strFileName = Get-ChildItem $InputFile | ForEach-Object{$_.Name}
    $strDBeditBatchCommand = "dbedit -local -f $($RemotePath + '/' + $strFileName) -continue_updating"
    
    # Copy our import file to the firewall
    Set-ScpFile -Computername $Firewall -Credential $Credential -Port $Port -LocalFile $InputFile -RemotePath $RemotePath
    
    # Create an SSH session to the firewall
    $objSession = New-SSHSession -Credential $Credential -ComputerName $Firewall
    
    # Run the script file via dbedit on the firewall
    $retVal = Invoke-SSHCommand -SessionId $objSession.SessionId -Command "$strDBeditBatchCommand"
    
    If ($retVal.ExitStatus -ne 0)
    {
        $retVal
    }
    Else
    {
        $retVal.ExitStatus
    }
    
    # Close the connection to the firewall
    $null = Remove-SSHSession -SessionId $objSession.SessionId
}


#endregion


#region Network objects


Function Export-CheckPointNetworkConfig 
{ 
    # used to get a list of all objects from the network_objects table via dbedit.
    # TODO:
    # Check if requirements are present
    # Stop using a file. redirect variable data into the -f argument.

    # REQUIREMENTS:
    # Requires Posh-SSH modules to be loaded

    # Description:
    # This script checks for Checkpoint reserved words, and duplicates...
    # There's no need to maintain more than one file. Just add to the master sheet of objects, and run the script.
    
    [CmdLetBinding()]
    Param
    (
        [Parameter(Mandatory = $True, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
        
        [Parameter(Mandatory = $True, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential,
        
        [Switch] $ReturnPsObject,
        
        [Parameter(DontShow)]
        [String] $Filter
    )
    
    # Variables
    $strCommandFileName = "getObjects.txt"
    $strDBeditPrintCommand = "printxml network_objects"
    $strSshDumpCommand = "dbedit -local -f $strCommandFileName"
    
    # Get the current firewall dump
    
    # Connect to the firewall via SSH session
    $objSession = New-SSHSession -Credential $Credential -ComputerName $Firewall
    
    # Invoke a command within the created session and create a command file
    Invoke-SSHCommand -SessionId $objSession.SessionId -Command ("echo `'$strDBeditPrintCommand`' `> $strCommandFileName") | Out-Null
    
    # Invoke a command to dump all the network_objects to an array variable.
    
    # Checkpoint doesn't know how to do XML, so have to fix...
    [xml] $objFirewallDump = '<objects>' + "`n" + $(Invoke-SSHCommand -SessionId $objSession.SessionId -Command "$strSshDumpCommand" | 
    ForEach-Object {$_.output}) + "`n" + '</objects>'
    
    If ($ReturnPsObject)
    {
        $bucket = @()
        
        If ($Filter)
        {
            $objSearch = ($objFirewallDump | Select-Xml -XPath "(/objects/network_objects_object[contains(text(), '$Filter')])").Node
            #($objFirewallDump | Select-Xml -XPath "//network_objects_object[text()='$Filter']").Node
        }
        Else
        {
            $objSearch = $objFirewallDump.objects.network_objects_object
        }
        
        Foreach ($obj in $objSearch)
        {
            $props = $obj | Get-Member -MemberType Property
            
            $objBuilder = New-Object -TypeName PSObject
            $objBuilder | Add-Member -MemberType NoteProperty -Name 'Name' -Value $obj.'#text'.Trim()
            
            Foreach ($prop in $props)
            {
                If (($obj.$($prop.Name) | Get-Member -MemberType Property | ForEach-Object Name) -eq '#cdata-section')
                {
                    $strValue = $obj.$($prop.Name).'#cdata-section'.Trim()
                }
                Else
                {
                    $strValue = $obj.$($prop.Name)
                }
                
                $objBuilder | Add-Member -MemberType NoteProperty -Name "$($prop.Name)" -Value $strValue
            }
            
            $bucket += $objBuilder
        }
        
        $bucket
    }
    Else
    {
        $objFirewallDump
    }
    
    # Clean up the SSH session
    $null = Remove-SSHSession -SessionId $objSession.SessionId
}


Function Get-CheckPointNetworkObject
{
    Param
    (
        [Parameter(Mandatory = $True, Position = 0, HelpMessage = 'Name of network object',
        ValueFromPipelineByPropertyName = $True, ValueFromPipeline = $True)]
        [String[]] $Name,
        
        [Parameter(Mandatory = $True, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
        
        [Parameter(Mandatory = $True, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential
    )
    
    Process
    {
        Foreach ($obj in $Name)
        {
            $Config = Export-CheckPointNetworkConfig -Firewall $Firewall -Credential $Credential -ReturnPsObject -Filter $obj
    
    
            $Config
        }
    }
}


Function New-CheckPointNetworkObject  
{
 
    [CmdLetBinding()]
    Param 
    (
        [Parameter(Mandatory = $True, Position = 0, HelpMessage = 'Name of network object',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Name, 
        
        [Parameter(Mandatory = $True, Position = 1, HelpMessage = 'Subnet address',
        ValueFromPipelineByPropertyName = $True)]
        [Alias('ipaddr','IPv4Address')]
        [IPAddress] $IP, 
        
        [Parameter(Mandatory = $True, Position = 2, HelpMessage = 'Netmask for the subnet',
        ValueFromPipelineByPropertyName = $True)]
        [Alias('Mask')]
        [String] $Netmask, 
        
        [Parameter(Position = 3, ValueFromPipelineByPropertyName = $True)]
        [ValidateSet(
                "aquamarine1","black","blue","burlywood4","dark orchid","darkseagreen3",
                "deepskyblue1","dodgerblue3","gray90","light coral","medium orchid",
                "medium slate blue","olive drab","orange","red","sienna"
        )][String] $Color, 
        
        [Parameter(Position = 4, ValueFromPipelineByPropertyName = $True)]
        [Alias('Comments')]
        [String] $Comment,
        
        [Parameter(Mandatory = $True, Position = 5, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
        
        [Parameter(Mandatory = $True, Position = 6, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential,
        
        [Int] $Port = 22
    )
    
    Begin
    {
        If (!((Get-CheckPointActiveShell -Firewall $Firewall -Credential $Credential) -match 'bash'))
        {
            Write-Error -Message ('Wrong shell for user: {0}' -f $Credential.UserName)
            Return
        }
    }
    
    Process
    {
        # Create our configuration file

        $guid = [GUID]::NewGuid().guid
        $OutputFile = $env:TEMP + '\' + $guid + '.dbedit'
    
        [System.Collections.ArrayList] $arrayCollectionOutput = @()
    
        $arrayCollectionOutput.Add(('create network {0}' -f $Name)) | Out-Null 
        $arrayCollectionOutput.Add(('modify network_objects {0} ipaddr {1}' -f $Name, $IP)) | Out-Null
        $arrayCollectionOutput.Add(('modify network_objects {0} netmask {1}' -f $Name, $Netmask)) | Out-Null
        $arrayCollectionOutput.Add(('modify network_objects {0} color "{1}"' -f $Name, $Color)) | Out-Null
        $arrayCollectionOutput.Add(('modify network_objects {0} comments "{1}"' -f $Name, $Comment)) | Out-Null
        $arrayCollectionOutput.Add("update_all") | Out-Null
    
        # Create the output file if it doesn't exist.
        Invoke-Touch -Path $OutputFile -Quiet | Out-Null
        
        # Get the full name of the file
        $Outputfile = Get-ChildItem -Path $Outputfile | ForEach-Object {$_.FullName}
        
        # Output the collection to the output file
        [System.IO.File]::WriteAllLines($OutputFile, ($arrayCollectionOutput)) | Out-Null 

        # Convert the file to Unix format, as we'll be sending this file to the firewall for processing.
        ConvertFrom-DosToUnix -FilePath $OutputFile | Out-Null
    
        Import-CheckPointBulkObject -Credential $Credential -Firewall $Firewall -Port $Port -InputFile $OutputFile 

        $null = Remove-Item -Path $OutputFile -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
    }
}


Function New-CheckPointHostObject  
{
    [CmdLetBinding()]
    Param 
    (
        [Parameter(Mandatory = $True, Position = 0, HelpMessage = 'Name of network object',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Name, 
        
        [Parameter(Mandatory = $True, Position = 1, HelpMessage = 'Subnet address',
        ValueFromPipelineByPropertyName = $True)]
        [Alias('ipaddr','IPv4Address')]
        [IPAddress] $IP,
        
        [Parameter(Mandatory = $True, Position = 3, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
        
        [Parameter(Mandatory = $True, Position = 4, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential,
        
        [Int] $Port = 22,
        
        [Parameter(Position = 5, ValueFromPipelineByPropertyName = $True)]
        [ValidateSet(
                "aquamarine1","black","blue","burlywood4","dark orchid","darkseagreen3",
                "deepskyblue1","dodgerblue3","gray90","light coral","medium orchid",
                "medium slate blue","olive drab","orange","red","sienna"
        )][String] $Color, 
        
        [Parameter(Position = 6, ValueFromPipelineByPropertyName = $True)]
        [Alias('Comments')]
        [String] $Comment
    )
    
    Begin
    {
        If (!((Get-CheckPointActiveShell -Firewall $Firewall -Credential $Credential) -match 'bash'))
        {
            Write-Error -Message ('Wrong shell for user: {0}' -f $Credential.UserName)
            Return
        }
    }
    
    Process
    {
        $guid = [GUID]::NewGuid().guid
        $OutputFile = $env:TEMP + '\' + $guid + '.dbedit'
    
        [System.Collections.ArrayList] $arrayCollectionOutput = @() # Empty array for building temporary output.
    
   
        $arrayCollectionOutput.Add("create host_plain $Name") | Out-Null
        $arrayCollectionOutput.Add("modify network_objects $Name ipaddr $IP") | Out-Null
        $arrayCollectionOutput.Add("modify network_objects $Name color `"$Color`"") | Out-Null
        $arrayCollectionOutput.Add("modify network_objects $Name comments `"$Comment`"") | Out-Null
        $arrayCollectionOutput.Add("update_all") | Out-Null
    
    
        # Create the output file if it doesn't exist.
        Invoke-Touch -Path $OutputFile -Quiet | Out-Null
        
        # Get the full name of the file
        $Outputfile = Get-ChildItem -Path $Outputfile | ForEach-Object {$_.FullName}
        
        # Output the collection to the output file
        [System.IO.File]::WriteAllLines($OutputFile, ($arrayCollectionOutput)) | Out-Null 

        # Convert the file to Unix format, as we'll be sending this file to the firewall for processing.
        ConvertFrom-DosToUnix -FilePath $OutputFile | Out-Null
    
        Import-CheckPointBulkObject -Credential $Credential -Firewall $Firewall -Port $Port -InputFile $OutputFile 

        $null = Remove-Item -Path $OutputFile -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
    }
}


Function New-CheckPointGroupObject  
{
    [CmdLetBinding()]
    Param 
    (
        [Parameter(Mandatory = $True, Position = 0, HelpMessage = 'Name of network object',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Name, 
        
        [Parameter(Position = 1, ValueFromPipelineByPropertyName = $True)]
        [ValidateSet(
                "aquamarine1","black","blue","burlywood4","dark orchid","darkseagreen3",
                "deepskyblue1","dodgerblue3","gray90","light coral","medium orchid",
                "medium slate blue","olive drab","orange","red","sienna"
        )][String] $Color, 
        
        [Parameter(Position = 2, ValueFromPipelineByPropertyName = $True)]
        [Alias('Comments')]
        [String] $Comment,
        
        [Parameter(Mandatory = $True, Position = 3, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
        
        [Parameter(Mandatory = $True, Position = 4, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential,
        
        [Int] $Port = 22
    )
    
    Begin
    {
        If (!((Get-CheckPointActiveShell -Firewall $Firewall -Credential $Credential) -match 'bash'))
        {
            Write-Error -Message ('Wrong shell for user: {0}' -f $Credential.UserName)
            Return
        }
    }
    
    Process
    {
        # Create our configuration file

        $guid = [GUID]::NewGuid().guid
        $OutputFile = $env:TEMP + '\' + $guid + '.dbedit'
    
        [System.Collections.ArrayList] $arrayCollectionOutput = @()
    
        $arrayCollectionOutput.Add(('create network_object_group {0}' -f $Name)) | Out-Null 
        $arrayCollectionOutput.Add(('modify network_objects {0} color "{1}"' -f $Name, $Color)) | Out-Null
        $arrayCollectionOutput.Add(('modify network_objects {0} comments "{1}"' -f $Name, $Comment)) | Out-Null
        $arrayCollectionOutput.Add("update_all") | Out-Null
    
        # Create the output file if it doesn't exist.
        Invoke-Touch -Path $OutputFile -Quiet | Out-Null
        
        # Get the full name of the file
        $Outputfile = Get-ChildItem -Path $Outputfile | ForEach-Object {$_.FullName}
        
        # Output the collection to the output file
        [System.IO.File]::WriteAllLines($OutputFile, ($arrayCollectionOutput)) | Out-Null 

        # Convert the file to Unix format, as we'll be sending this file to the firewall for processing.
        ConvertFrom-DosToUnix -FilePath $OutputFile | Out-Null
    
        Import-CheckPointBulkObject -Credential $Credential -Firewall $Firewall -Port $Port -InputFile $OutputFile 

        $null = Remove-Item -Path $OutputFile -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
    }
}


Function Get-CheckPointGroupObject
{

}


Function Add-CheckPointObjectToGroup
{
    Param
    (
        [Parameter(Mandatory = $True, Position = 0, ValueFromPipelineByPropertyName = $True)]
        [String] $Name,
        
        [Parameter(Mandatory = $True, Position = 1, ValueFromPipelineByPropertyName = $True)]
        [String] $Group,
        
        [Parameter(Mandatory = $True, Position = 2, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
        
        [Parameter(Mandatory = $True, Position = 3, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential,
        
        [Int] $Port = 22
    )
    
    Process
    {
        $guid = [GUID]::NewGuid().guid
        $strTempFile = $env:TEMP + '\' + $guid + '.dbedit'
    
        Invoke-Touch -Path $strTempFile -Quiet
    
        $InputFile = Get-ChildItem -Path $strTempFile | ForEach-Object {$_.FullName}
    
        [System.Collections.ArrayList] $arrayCollectionOutput = @()
 
        $arrayCollectionOutput.Add(("addelement network_objects {0} `'`' network_objects:{1}" -f $Group, $Name)) | 
        Out-Null
    
        $arrayCollectionOutput.Add('update_all') | Out-Null 
    
        [System.IO.File]::WriteAllLines($InputFile, ($arrayCollectionOutput)) | Out-Null 

        ConvertFrom-DosToUnix -FilePath $InputFile | Out-Null
    
        Import-CheckPointBulkObject -Credential $Credential -Firewall $Firewall -Port $Port -InputFile $InputFile
    
        $null = Remove-Item -Path $InputFile -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
    }
}



Function Search-CheckPointWhereUsed
{
    Param
    (
        [String] $Name,
        
        [ValidateSet('network_objects','services')]
        [String] $Table = 'network_objects',
        
        [Parameter(Mandatory = $True, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
        
        [Parameter(Mandatory = $True, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential,
        
        [Int] $Port = 22
    )
    
    # Variables
    $strCommandFileName = "getObjects.txt"
    $strDBeditPrintCommand = "printxml $Table"
    $strSshDumpCommand = "dbedit -local -f $strCommandFileName"
    
    $guid = [GUID]::NewGuid().guid
    $strTempFile = $env:TEMP + '\' + $guid + '.dbedit'
    
    Invoke-Touch -Path $strTempFile -Quiet
    
    $InputFile = Get-ChildItem -Path $strTempFile | ForEach-Object {$_.FullName}
    
    [System.Collections.ArrayList] $arrayCollectionOutput = @()
 
    $arrayCollectionOutput.Add(("addelement network_objects {0} `'`' network_objects:{1}" -f $Group, $Name)) | 
    Out-Null
    
    $arrayCollectionOutput.Add('update_all') | Out-Null 
    
    [System.IO.File]::WriteAllLines($InputFile, ($arrayCollectionOutput)) | Out-Null 

    ConvertFrom-DosToUnix -FilePath $InputFile | Out-Null
    
    Import-CheckPointBulkObject -Credential $Credential -Firewall $Firewall -Port $Port -InputFile $InputFile
    
    $null = Remove-Item -Path $InputFile -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
}


#endregion


#region DEV

<#
Function Export-CheckPointFWPolicyConfig
{
 
     
    [CmdLetBinding()]
    Param
    (
        [Parameter(Mandatory = $True, HelpMessage = 'Checkpoint Firewall',
        ValueFromPipelineByPropertyName = $True)]
        [String] $Firewall,
         
        [Parameter(Mandatory = $True, HelpMessage = 'Credentials with bash shell')]
        [PSCredential] [System.Management.Automation.Credential()] $Credential,
         
        [Switch] $ReturnPsObject,
         
        [Parameter(DontShow)]
        [String] $Filter
    )
     
    # Variables
    $strCommandFileName = "getObjects.txt"
    $strDBeditPrintCommand = "printxml fw_policies"
    $strSshDumpCommand = "dbedit -local -f $strCommandFileName"
     
    # Get the current firewall dump
     
    # Connect to the firewall via SSH session
    $objSession = New-SSHSession -Credential $Credential -ComputerName $Firewall
     
    # Invoke a command within the created session and create a command file
    Invoke-SSHCommand -SessionId $objSession.SessionId -Command ("echo `'$strDBeditPrintCommand`' `> $strCommandFileName") | Out-Null
     
    # Invoke a command to dump all the network_objects to an array variable.
     
    # Checkpoint doesn't know how to do XML, so have to fix...
    [xml] $objFirewallDump = '<objects>' + "`n" + $(Invoke-SSHCommand -SessionId $objSession.SessionId -Command "$strSshDumpCommand" |
    ForEach-Object {$_.output}) + "`n" + '</objects>'
     
    If ($ReturnPsObject)
    {
        $bucket = @()
         
        If ($Filter)
        {
            $objSearch = ($objFirewallDump | Select-Xml -XPath "(/objects/network_objects_object[contains(text(), '$Filter')])").Node
            #($objFirewallDump | Select-Xml -XPath "//network_objects_object[text()='$Filter']").Node
        }
        Else
        {
            $objSearch = $objFirewallDump.objects.fw_policies_object
        }
         
        Foreach ($obj in $objSearch)
        {
            $props = $obj | Get-Member -MemberType Property
             
            $objBuilder = New-Object -TypeName PSObject
            $objBuilder | Add-Member -MemberType NoteProperty -Name 'Name' -Value $obj.'#text'.Trim()
             
            Foreach ($prop in $props)
            {
                If (($obj.$($prop.Name) | Get-Member -MemberType Property | ForEach-Object Name) -eq '#cdata-section')
                {
                    $strValue = $obj.$($prop.Name).'#cdata-section'.Trim()
                }
                Else
                {
                    $strValue = $obj.$($prop.Name)
                }
                 
                $objBuilder | Add-Member -MemberType NoteProperty -Name "$($prop.Name)" -Value $strValue
            }
             
            $bucket += $objBuilder
        }
         
        $bucket
    }
    Else
    {
        $objFirewallDump
    }
     
    # Clean up the SSH session
    $null = Remove-SSHSession -SessionId $objSession.SessionId
}
#>


#endregion