Our Score
Click to rate this post!
[Total: 1 Average: 5]

Recently, I have found Pode and Pode.Web and I were so excited and wanted to create something with it. Then my boss decided that he wanted a new phone book to replace the current SharePoint list, and I saw an opportunity to use Pode.Web. For this example, I assume that Pode.Web is already downloaded and installed. My end goals are:

  1. Have a web-based phone book that pulls data from Active Directory
    1. Changes in the AD must be reflected as quickly as possible.
    2. Will be hosted by an IIS web server
    3. PowerShell 7 will be used
    4. This is a public phone book; authentication is not required.
  2. All Data comes from the Active Directory user attributes, which are filled during the user account creation
    1. Title – User Title
    2. Name – Self-Explaining
    3. co – Long Name for Country
    4. Office Phone – we use this for the desk phone
    5. Department – User department
    6. Mail – User email
    7. mobile – User Mobile Number
    8. employeeNumber – Internally Used Attributes
    9. employeeType – Internally Used Attributes
  3. There are some permanent contacts – these are coming from Active Directory contact objects located in an AD Organization Unit

Let’s begin.

To start the phone book, I use this simple script. It imports the module, adds IIS authentication, adds a route to the folder pages where our pages are, adds logging, and finally adds our two pages.

Import-Module -Name Pode.Web

Start-PodeServer {
    Add-PodeEndpoint -Address Your.Server.Ip.Address -Port 8090 -Protocol Http  
    Use-PodeWebTemplates -Title 'Phonebook' -Theme Light

    Enable-PodeSessionMiddleware -Duration 120 -Extend
    Add-PodeAuthIIS -Name 'IISAuth' -ScriptBlock {
    param($user)
    return @{ User = $user}
    }

    Add-PodeRoute -Method Get -Path '/pages' -Authentication 'IISAuth' -ScriptBlock {
        Write-PodeJsonResponse -Value @{ User = $WebEvent.Auth.User }
    }

    New-PodeLoggingMethod -File -Name 'requests' -MaxSize 10MB | Enable-PodeRequestLogging
    New-PodeLoggingMethod -Terminal | Enable-PodeErrorLogging

    Use-PodeWebPages .\pages\Tabs.ps1
    Use-PodeWebPages .\pages\theme.ps1
}
Code language: PowerShell (powershell)


Our pages are one for theme selection and the phone-book itself.
The theme page is straightforward—it adds a web page, a single container, and a few buttons inside the container to select a theme or reset to the default one.

Add-PodeWebPage -Name 'Theme Selector' -ScriptBlock {
    New-PodeWebContainer -Content @(
        New-PodeWebButton -Name 'Dark' -ScriptBlock {
            Update-PodeWebTheme -Name Dark
        }
        New-PodeWebButton -Name 'Light' -ScriptBlock {
            Update-PodeWebTheme -Name Light
        }   
        New-PodeWebButton -Name 'Terminal' -ScriptBlock {
            Update-PodeWebTheme -Name Terminal
        }
        New-PodeWebButton -Name 'Reset' -ScriptBlock {
            Reset-PodeWebTheme
        }
    )
}Code language: PowerShell (powershell)

The main page in our little project is the tabs page. I have decided to use tabs due to the nature of the organization where I work. The page opens on the all users tab, the following two tabs are for the main branches, and the last one is for the permanent contacts. With Pode, you always have nesting, but it is logical.

Add-PodeWebPage -Name 'Phonebook' -NoSidebar -NoTitle -ScriptBlock {
    New-PodeWebTabs -Tabs @(
        New-PodeWebTab -Name All -Layouts @(
            New-PodeWebContainer -Content @(
                New-PodeWebTable -NameCode language: PHP (php)

Start with adding a web page, then the main tab, which contains all other tabs, then the first tab, a web container in it, and I used a table inside the container. Repeat as many tabs(times) as you need. My example scripts looks like this, please change the OU path to reflect your structure.

Add-PodeWebPage -Name 'Phonebook' -NoSidebar -NoTitle -ScriptBlock {
    New-PodeWebTabs -Tabs @(
        New-PodeWebTab -Name All -Layouts @(
            New-PodeWebContainer -Content @(
                New-PodeWebTable -Name 'All USERS' -SimpleFilter -SimpleSort -Compact -Message "Please get in touch with the Service Desk 6415678 for any questions or incorrect information" -ScriptBlock {
                    foreach ($user in (Get-ADUser -Filter * -SearchBase "OU=YORUSERSOU,OU=contoso,OU=COM" -Properties Title, Name, Mail, co, OfficePhone, Department, employeeNumber, `
                                employeeType, mobile | Select-Object Title, Name, Mail, OfficePhone, Department, employeeNumber, employeeType, co, mobile)) {
                        if (($user.employeeNumber -eq $null) -or ($user.employeeNumber -like '*000*')) {
                            $user.employeeNumber = "NON CE"
                            $user.employeeType = "NON CE"
                        }
                        [ordered]@{
                            Title       = $user.Title
                            Name        = $user.Name
                            Mail        = $user.Mail
                            OfficePhone = $user.OfficePhone
                            Mobile      = $user.Mobile
                            Department  = $user.Department
                            CEPost      = $user.employeeNumber
                            JobTitle    = $user.employeeType
                            Country     = $user.co
                            #  Actions     = @(
                            #      New-PodeWebButton -Name 'Stop' -Icon 'Stop-Circle' -IconOnly -ScriptBlock {
                            #          Stop-Service -Name $WebEvent.Data.Value -Force | Out-Null
                            #          Show-PodeWebToast -Message "$($WebEvent.Data.Value) stopped"
                            #          Sync-PodeWebTable -Id $ElementData.Parent.ID
                            #      }
                            #      New-PodeWebButton -Name 'Start' -Icon 'Play-Circle' -IconOnly -ScriptBlock {
                            #          Start-Service -Name $WebEvent.Data.Value -Force | Out-Null
                            #          Show-PodeWebToast -Message "$($WebEvent.Data.Value) started"
                            #          Sync-PodeWebTable -Id $ElementData.Parent.ID
                            #      }
                            #  )
                        }
                    }
                } -Columns @(
                    Initialize-PodeWebTableColumn -Key Title -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Name -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Mail -Alignment Left -Icon sort -Width 0
                    Initialize-PodeWebTableColumn -Key OfficePhone -Alignment Left -Icon sort-numeric-variant
                    Initialize-PodeWebTableColumn -Key Mobile -Alignment Left -Icon sort-numeric-variant
                    Initialize-PodeWebTableColumn -Key Department -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key CEPost -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key JobTitle -Alignment Left -Icon sort -Width 0
                    Initialize-PodeWebTableColumn -Key Country -Alignment Left -Icon sort
                )
            )
        )
        New-PodeWebTab -Name EUFOR -Layouts @(
            New-PodeWebContainer -Content @(
                New-PodeWebTable -Name 'BRANCH01 USERS' -SimpleFilter -SimpleSort -ScriptBlock {
                    foreach ($user in (Get-ADUser -Filter * -SearchBase "OU=MAINBRANCH01,OU=Enabled Users,OU=YORUSERSOU,OU=contoso,OU=COM" -Properties Title, Name, co, Mail, OfficePhone, Department, employeeNumber, `
                                employeeType, mobile | Select-Object Title, Name, Mail, OfficePhone, Department, employeeNumber, employeeType, co, mobile)) {
                        if (($user.employeeNumber -eq $null) -or ($user.employeeNumber -like '*000*')) {
                            $user.employeeNumber = "NON CE"
                            $user.employeeType = "NON CE"
                        }
                        [ordered]@{
                            Title       = $user.Title
                            Name        = $user.Name
                            Mail        = $user.Mail
                            OfficePhone = $user.OfficePhone
                            Mobile      = $user.Mobile
                            Department  = $user.Department
                            CEPost      = $user.employeeNumber
                            JobTitle    = $user.employeeType
                            Country     = $user.co
                            #   Actions     = @(
                            #       New-PodeWebButton -Name 'Stop' -Icon 'Stop-Circle' -IconOnly -ScriptBlock {
                            #           Stop-Service -Name $WebEvent.Data.Value -Force | Out-Null
                            #           Show-PodeWebToast -Message "$($WebEvent.Data.Value) stopped"
                            #           Sync-PodeWebTable -Id $ElementData.Parent.ID
                            #       }
                            #       New-PodeWebButton -Name 'Start' -Icon 'Play-Circle' -IconOnly -ScriptBlock {
                            #           Start-Service -Name $WebEvent.Data.Value -Force | Out-Null
                            #           Show-PodeWebToast -Message "$($WebEvent.Data.Value) started"
                            #           Sync-PodeWebTable -Id $ElementData.Parent.ID
                            #       }
                            #   )
                        } 
                    }
                } -Columns @(
                    Initialize-PodeWebTableColumn -Key Title -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Name -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Mail -Alignment Left -Icon sort -Width 0
                    Initialize-PodeWebTableColumn -Key OfficePhone -Alignment Left -Icon sort-numeric-variant
                    Initialize-PodeWebTableColumn -Key Mobile -Alignment Left -Icon sort-numeric-variant
                    Initialize-PodeWebTableColumn -Key Department -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key JobTitle -Alignment Left -Icon sort -Width 0
                    Initialize-PodeWebTableColumn -Key Country -Alignment Left -Icon sort
                )
            )
        )
        New-PodeWebTab -Name NATO -Layouts @(
            New-PodeWebContainer -Content @(
                New-PodeWebTable -Name 'BRANCH02 USERS' -SimpleFilter -SimpleSort -ScriptBlock {
                    foreach ($user in (Get-ADUser -Filter * -SearchBase "OU=BRANCH02,OU=YOURUSERSOU,OU=contoso,OU=COM" -Properties Title, Name, Mail, OfficePhone, Department, employeeNumber, `
                    employeeType, co, mobile | Select-Object Title, Name, Mail, OfficePhone, Department, employeeNumber, employeeType, co, mobile)) {
                        if (($user.employeeNumber -eq $null) -or ($user.employeeNumber -like '*000*')) {
                            $user.employeeNumber = "NON CE"
                            $user.employeeType = "NON CE"
                        }
                        [ordered]@{
                            Title       = $user.Title
                            Name        = $user.Name
                            Mail        = $user.Mail
                            OfficePhone = $user.OfficePhone
                            Mobile      = $user.Mobile
                            Department  = $user.Department
                            CEPost      = $user.employeeNumber
                            JobTitle    = $user.employeeType
                            Country     = $user.co
                            #  Actions     = @(
                            #      New-PodeWebButton -Name 'Stop' -Icon 'Stop-Circle' -IconOnly -ScriptBlock {
                            #          Stop-Service -Name $WebEvent.Data.Value -Force | Out-Null
                            #          Show-PodeWebToast -Message "$($WebEvent.Data.Value) stopped"
                            #          Sync-PodeWebTable -Id $ElementData.Parent.ID
                            #      }
                            #      New-PodeWebButton -Name 'Start' -Icon 'Play-Circle' -IconOnly -ScriptBlock {
                            #          Start-Service -Name $WebEvent.Data.Value -Force | Out-Null
                            #          Show-PodeWebToast -Message "$($WebEvent.Data.Value) started"
                            #          Sync-PodeWebTable -Id $ElementData.Parent.ID
                            #      }
                            #  )
                        } 
                
                    }
                } -Columns @(
                    Initialize-PodeWebTableColumn -Key Title -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Name -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Mail -Alignment Left -Icon sort -Width 0
                    Initialize-PodeWebTableColumn -Key OfficePhone -Alignment Left -Icon sort-numeric-variant
                    Initialize-PodeWebTableColumn -Key Mobile -Alignment Left -Icon sort-numeric-variant
                    Initialize-PodeWebTableColumn -Key Department -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Department -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key JobTitle -Alignment Left -Icon sort -Width 0
                    Initialize-PodeWebTableColumn -Key Country -Alignment Left -Icon sort
                )
            )
        )
        New-PodeWebTab -Name Permanent -Layouts @(
            New-PodeWebContainer -Content @(
                New-PodeWebTable -Name 'Permanent Contacts' -SimpleFilter -SimpleSort -ScriptBlock {
                    foreach ($contact in (Get-ADObject -Filter { (objectClass -eq "contact") } -Properties * -SearchBase "OU=UserContacts,OU=contoso,OU=COM" `
                            | Select-Object Title, Name, Mail, OfficePhone, Department, employeeNumber, employeeType, co, telephoneNumber)) {
                        if (($contact.employeeNumber -eq $null) -or ($contact.employeeNumber -like '*000*')) {
                            $contact.employeeNumber = "NON CE"
                            $contact.employeeType = "NON CE"
                        }
                        [ordered]@{
                            Title      = $contact.Title
                            Name       = $contact.Name
                            Mail       = $contact.Mail
                            Phone      = $contact.telephoneNumber
                            Department = $contact.Department
                            CEPost     = $contact.employeeNumber
                            JobTitle   = $contact.employeeType
                            Country    = $contact.co
                        }
                    }
                } -Columns @(
                    Initialize-PodeWebTableColumn -Key Title -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Name -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Mail -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Phone -Alignment Left -Icon sort-numeric-variant
                    Initialize-PodeWebTableColumn -Key Department -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Department -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key JobTitle -Alignment Left -Icon sort
                    Initialize-PodeWebTableColumn -Key Country -Alignment Left -Icon sort
                )
            )
        )
    )
}Code language: PHP (php)

Copy theme.ps1 and tabs.ps1 to the pages folder. Feel free to change the names to your liking. Then what’s left is to setup IIS server for Pode. There is a great guide how to do it here written by the badgerati, the creator of Pode and Pode.Web. If necessary grant the IUSR read & execute permissions over the PowerShell 7 folder in program files.

Pode is great, I’ve made an account creator from with it for my Service Desk guys and few other simple projects, it is stable and reliable. Give it a try!

That’s All Folks!

Any question, post a comment.

Our Score
Click to rate this post!
[Total: 1 Average: 5]