functions/get-fscpslcssharedassetlist.ps1


<#
    .SYNOPSIS
        Retrieves a list of shared assets from D365 LCS.
         
    .DESCRIPTION
        The Get-FSCPSLCSSharedAssetList function uses Microsoft Playwright to automate the login process to LCS (Lifecycle Services)
        and retrieves a list of shared assets based on the specified asset file type. It handles authentication, session management,
        and API requests to fetch the required data.
         
    .PARAMETER AssetFileType
        The type of asset file to retrieve. This parameter is mandatory and defaults to "SoftwareDeployablePackage".
         
    .EXAMPLE
        PS C:\> Get-FSCPSLCSSharedAssetList -AssetFileType SoftwareDeployablePackage
         
        Retrieves a list of shared assets of type "SoftwareDeployablePackage" from D365 LCS.
         
    .NOTES
        - This function uses Microsoft Playwright for browser automation.
        - Author: Oleksandr Nikolaiev (@onikolaiev)
#>

function Get-FSCPSLCSSharedAssetList {
    [CmdletBinding()]
    [OutputType()]
    param(
        [Parameter(Mandatory=$false)]
        [AssetFileType]$AssetFileType = [AssetFileType]::SoftwareDeployablePackage
    )
    begin {
        Invoke-TimeSignal -Start
        # Create a Playwright browser instance
        $playwright = [Microsoft.Playwright.Playwright]::CreateAsync().GetAwaiter().GetResult()

        $browser = $playwright.Chromium.LaunchAsync([Microsoft.Playwright.BrowserTypeLaunchOptions]@{ Headless = $true }).Result

        $context = $browser.NewContextAsync(@{
            StorageStatePath = $coockiesPath 
        }).GetAwaiter().GetResult()
    }
    PROCESS {

        # Open a new browser page
        $page = $context.NewPageAsync().Result
        $lcsUsername = Get-PSFConfigValue -FullName "fscps.lcs.settings.all.lcsUsername"
        $lcsPassword = Get-PSFConfigValue -FullName "fscps.lcs.settings.all.lcsPassword"


        if(-not (Test-Path "$coockiesPath"))
        {
            # Navigate to the login page
            $page.GotoAsync("https://lcs.dynamics.com/Logon/ADLogon").Wait()

            # Fill in the username/email field
            $page.FillAsync("input[type='email']", "$lcsUsername").Wait()

            # Click the "Next" button
            $page.ClickAsync("input[type='submit']").Wait()

            # Wait for the password field to appear
            $page.WaitForSelectorAsync("input[type='password']").Wait()

            # Fill in the password field
            $page.FillAsync("input[type='password']", "$lcsPassword").Wait()

            # Click the "Sign in" button
            $page.ClickAsync("input[type='submit']").Wait()

            $page.ClickAsync("input[type='submit']").Wait()

            # Wait for the login process to complete (adjust selector as needed)
            $page.WaitForNavigationAsync().Wait()
            $page.Context.StorageStateAsync(@{
                Path = $coockiesPath
            }).Wait()
        }

        $apiRequestContext = $page.APIRequest
        $requestResult = $apiRequestContext.GetAsync("https://lcs.dynamics.com/FileAsset/GetSharedAssets/?assetKind=$([int]$AssetFileType)").GetAwaiter().GetResult()
        $result = $requestResult.JsonAsync().GetAwaiter().GetResult()
        $assetList = $result.ToString() | ConvertFrom-Json
        return $assetList.Data.Assets
    }
    END {
        # Close the browser
        $browser.CloseAsync().Wait()
        Invoke-TimeSignal -End
    }    
}