AzureArcConnectedAgentManagement.psm1
Function Connect-AzureArcNode { <# .Synopsis Connects the local machine to Azure Arc. .DESCRIPTION Connects the local machine to Azure Arc. .PARAMETER AccessToken .PARAMETER ServicePrincipalSecret Azure AD Application ServicePrincipal Secret .PARAMETER ServicePrincipalID Azure AD Application ServicePrincipal ID .PARAMETER DeviceLogin Specifies the Azure Arc onboarding method .PARAMETER TenantID Specifies the Azure Active Directory Tenant ID .PARAMETER ResourceGroup Specifies the Azure Resource Group Name .PARAMETER SubscriptionID Specifies the Azure Subscription ID .PARAMETER Tags Specifies the Azure Resource Tags .EXAMPLE Connect-AzureArcNode -DeviceLogin -TenantID XXXX-XXXX-XXXX-XXXX-XXXXXX -ResourceGroup "Resource Group Name" -Location "West Europe" -SubscriptionID XXXX-XXXX-XXXX-XXXX-XXXXXX .EXAMPLE Connect-AzureArcNode -ServicePrincipalID XXXX-XXXX-XXXX-XXXX-XXXXXX -ServicePrincipalSecret "XXXX-XXXX-XXXX-XXXX-XXXXXX" -TenantID XXXX-XXXX-XXXX-XXXX-XXXXXX -ResourceGroup "Resource Group Name" -Location "West Europe" -SubscriptionID XXXX-XXXX-XXXX-XXXX-XXXXXX .EXAMPLE #Define Azure Resource Tags Hashtable $Tags = @{ Datacenter = "Value1" City = "Value2" StateOrDistrict = "Value3" CountryOrRegion = "Value4" MinuTag= "Value5" } Connect-AzureArcNode -ServicePrincipalID XXXX-XXXX-XXXX-XXXX-XXXXXX -ServicePrincipalSecret "XXXX-XXXX-XXXX-XXXX-XXXXXX" -TenantID XXXX-XXXX-XXXX-XXXX-XXXXXX -ResourceGroup "Resource Group Name" -Location "West Europe" -SubscriptionID XXXX-XXXX-XXXX-XXXX-XXXXXX -Tags $Tags #> [CmdletBinding(DefaultParameterSetName = 'ServicePrincipal')] Param( [Parameter(Mandatory = $true,ParameterSetName = 'AccessToken',HelpMessage = 'Enter Access Token')] $AccessToken, [Parameter(Mandatory = $true,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter ServicePrincipal')] $ServicePrincipalSecret, [Parameter(Mandatory = $true,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter ServicePrincipal ID')] $ServicePrincipalID, [Parameter(Mandatory = $true,ParameterSetName = 'DeviceLogin')] [Switch]$DeviceLogin, [Parameter(Mandatory = $true,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter')] [Parameter(Mandatory = $true,ParameterSetName = 'DeviceLogin',HelpMessage = 'Enter')] [String]$TenantID, [Parameter(Mandatory = $true,ParameterSetName = 'AccessToken',HelpMessage = 'Enter')] [Parameter(Mandatory = $true,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter')] [Parameter(Mandatory = $true,ParameterSetName = 'DeviceLogin',HelpMessage = 'Enter')] [String]$ResourceGroup, [Parameter(Mandatory = $true,ParameterSetName = 'AccessToken',HelpMessage = 'Enter')] [Parameter(Mandatory = $true,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter')] [Parameter(Mandatory = $true,ParameterSetName = 'DeviceLogin',HelpMessage = 'Enter')] [String]$Location, [Parameter(Mandatory = $true,ParameterSetName = 'AccessToken',HelpMessage = 'Enter')] [Parameter(Mandatory = $true,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter')] [Parameter(Mandatory = $true,ParameterSetName = 'DeviceLogin',HelpMessage = 'Enter')] [String]$SubscriptionID, [Parameter(Mandatory = $false,ParameterSetName = 'AccessToken',HelpMessage = 'Enter')] [Parameter(Mandatory = $false,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter')] [Parameter(Mandatory = $false,ParameterSetName = 'DeviceLogin',HelpMessage = 'Enter')] [HashTable]$Tags ) Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ If($PSBoundParameters.ContainsKey("ServicePrincipalID")){ $Parameters = '& $AZCMAGENTLocation connect --service-principal-id $ServicePrincipalID --service-principal-secret $ServicePrincipalSecret --tenant-id $TenantID --subscription-id $SubscriptionID --resource-group $ResourceGroup --location $Location' } ElseIf($PSBoundParameters.ContainsKey("AccessToken")){ $Parameters = '& $AZCMAGENTLocation connect --access-token $AccessToken --subscription-id $SubscriptionID --resource-group $ResourceGroup --location $Location' } ElseIf($PSBoundParameters.ContainsKey("DeviceLogin")){ $Parameters = '& $AZCMAGENTLocation connect --tenant-id $TenantID --subscription-id $SubscriptionID --resource-group $ResourceGroup --location $Location' } If($PSBoundParameters.ContainsKey("Tags")){ $ProcessedTags = ($Tags.GetEnumerator()| ForEach-Object -Process { "$($PSItem.key)" + "=" + "'$($PSItem.value)'" }) -join "," $Parameters = "$Parameters --tags $ProcessedTags" } Try{ Write-Verbose -Message "& (Executing $AZCMAGENTLocation with the following parameters: $Parameters)" Invoke-Expression $Parameters } Catch{ $Error[0] } } End{} } Function Disconnect-AzureArcNode { <# .Synopsis Disconnects the local machine from Azure Arc service. .DESCRIPTION Disconnects the local machine from Azure Arc service. .PARAMETER AccessToken .PARAMETER ServicePrincipalSecret .PARAMETER ServicePrincipalID .PARAMETER DeviceLogin .EXAMPLE Disconnect-AzureArcNode -ServicePrincipalSecret XXXX-XXXX-XXXX-XXXX-XXXXXX -ServicePrincipalID XXXX-XXXX-XXXX-XXXX-XXXXXX .EXAMPLE Disconnect-AzureArcNode -AccessToken $MyAccessToken .EXAMPLE Disconnect-AzureArcNode -DeviceLogin #> [CmdletBinding(DefaultParameterSetName = 'ServicePrincipal')] Param( [Parameter(Mandatory = $true,ParameterSetName = 'AccessToken',HelpMessage = 'Enter Access Token')] $AccessToken, [Parameter(Mandatory = $true,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter ServicePrincipal')] $ServicePrincipalSecret, [Parameter(Mandatory = $true,ParameterSetName = 'ServicePrincipal',HelpMessage = 'Enter ServicePrincipal ID')] $ServicePrincipalID, [Parameter(Mandatory = $true,ParameterSetName = 'DeviceLogin')] [Switch]$DeviceLogin ) Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ If($PSBoundParameters.ContainsKey("ServicePrincipalID")){ $Parameters = "& $AZCMAGENTLocation disconnect --service-principal-id $ServicePrincipalID --service-principal-secret $ServicePrincipalSecret" } ElseIf($PSBoundParameters.ContainsKey("AccessToken")){ $Parameters = "& $AZCMAGENTLocation disconnect --access-token $AccessToken" } ElseIf($PSBoundParameters.ContainsKey("DeviceLogin")){ $Parameters = "& $AZCMAGENTLocation disconnect " } Try{ Write-Verbose -Message "Executing $AZCMAGENTLocation with the following parameters: $Parameters" Invoke-Expression $Parameters } Catch{ $Error[0] } } End{} } Function Get-AzureArcNodeAgentInformation { <# .Synopsis Outputs information about the Azure Arc Agent. .DESCRIPTION Outputs information about the Azure Arc Agent. .PARAMETER OutPutType Specifies the output type. Type can be JSON or RAW. .EXAMPLE Get-AzureArcNodeAgentInformation -OutPutType JSON .EXAMPLE Get-AzureArcNodeAgentInformation -OutPutType RAW #> [CmdletBinding()] Param( [Parameter(Mandatory = $True,HelpMessage = 'Enter the output type')] [ValidateSet("JSON", "RAW")] $OutPutType = "JSON" ) Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ If($OutPutType -eq "JSON"){ $Parameters = '& $AZCMAGENTLocation show -j' $AgentstatusHash = [ordered]@{} $QueryResults = Invoke-Expression $Parameters | ConvertFrom-Json $QueryResults.psobject.properties | Sort-Object -Property Name | ForEach-Object { $AgentstatusHash[$((Get-Culture).TextInfo.ToTitleCase($PSItem.Name))] = $PSItem.Value } Return $AgentstatusHash } Else{ $Parameters = '& $AZCMAGENTLocation show' $QueryResults = Invoke-Expression $Parameters Return $QueryResults } Try{ Write-Verbose -Message "Executing $AZCMAGENTLocation with the following parameters: $Parameters" } Catch{ $Error[0] } } End{} } Function Test-AzureArcNodeNetworkConnectivity { <# .Synopsis Tests the connectivity of Azure Arc Network Service .DESCRIPTION Tests the connectivity of Azure Arc Network Service .PARAMETER Location Specifies the Azure Region. .PARAMETER OutPutType Specifies the output type. Type can be JSON or RAW. .EXAMPLE Test-AzureArcNodeNetworkConnectivity -OutPutType JSON .EXAMPLE Test-AzureArcNodeNetworkConnectivity -OutPutType RAW #> [CmdletBinding()] Param( [Parameter(Mandatory = $True,HelpMessage = 'Enter the Azure Region')] [String]$Location, [Parameter(Mandatory = $True,HelpMessage = 'Enter the output type')] [ValidateSet("JSON", "RAW")] $OutPutType = "JSON" ) Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ If($OutPutType -eq "JSON"){ $Parameters = '& $AZCMAGENTLocation check -l $Location -j' } Else{ $Parameters = '& $AZCMAGENTLocation check -l $Location' } $QueryResults = Invoke-Expression $Parameters Return $QueryResults } End{} } Function Set-AzureArcNodeConfiguration { <# .Synopsis Configures settings for the local Azure Arc Agent .DESCRIPTION Configures settings for the local Azure Arc Agent .PARAMETER ConfigurationName Specifies the setting name. Possible values are incomingconnections.ports,proxy.url,extensions.allowlist,extensions.blocklist,proxy.bypass,guestconfiguration.enabled,extensions.enabled .PARAMETER ConfigurationValue Specifies the setting value. .PARAMETER OutPutType .EXAMPLE Set-AzureArcNodeConfiguration -ConfigurationName proxy.url -ConfigurationValue "http://proxy.Kaido.ee:8530" -OutPutType JSON #> [CmdletBinding()] Param( [Parameter(Mandatory = $True,HelpMessage = 'Enter the Configuration Name')] [ValidateSet("incomingconnections.ports","proxy.url","extensions.allowlist","extensions.blocklist","proxy.bypass","guestconfiguration.enabled","extensions.enabled")] $ConfigurationName, [Parameter(Mandatory = $True,HelpMessage = 'Enter the Configuration Value')] $ConfigurationValue, [Parameter(Mandatory = $True,HelpMessage = 'Enter the output type')] [ValidateSet("JSON", "RAW")] $OutPutType = "JSON" ) Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ If($OutPutType -eq "JSON"){ $Parameters = '& $AZCMAGENTLocation config set $ConfigurationName $ConfigurationValue -j' } Else{ $Parameters = '& $AZCMAGENTLocation config set $ConfigurationName $ConfigurationValue' } $SetConfigResults = Invoke-Expression $Parameters Return $SetConfigResults } End{} } Function Get-AzureArcNodeConfiguration { <# .Synopsis Queries the local Azure Arc Agent configuration .DESCRIPTION Queries the local Azure Arc Agent configuration .PARAMETER ConfigurationName Specifies the setting name. Possible values are incomingconnections.ports,proxy.url,extensions.allowlist,extensions.blocklist,proxy.bypass,guestconfiguration.enabled,extensions.enabled .PARAMETER OutPutType .EXAMPLE Get-AzureArcNodeConfiguration -ConfigurationName proxy.url -OutPutType JSON #> [CmdletBinding()] Param( [Parameter(Mandatory = $True,HelpMessage = 'Enter the Configuration Name')] [ValidateSet("incomingconnections.ports","proxy.url","extensions.allowlist","extensions.blocklist","proxy.bypass","guestconfiguration.enabled","extensions.enabled")] $ConfigurationName, [Parameter(Mandatory = $True,HelpMessage = 'Enter the output type')] [ValidateSet("JSON", "RAW")] $OutPutType = "JSON" ) Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ If($OutPutType -eq "JSON"){ $Parameters = '& $AZCMAGENTLocation config get $ConfigurationName $ConfigurationValue -j' } Else{ $Parameters = '& $AZCMAGENTLocation config get $ConfigurationName $ConfigurationValue' } $SetConfigResults = Invoke-Expression $Parameters Return $SetConfigResults } End{} } Function Clear-AzureArcNodeConfiguration { <# .Synopsis Resets the local Azure Arc Agent configurationf or specific setting .DESCRIPTION Resets the local Azure Arc Agent configurationf or specific setting .PARAMETER ConfigurationName Specifies the setting name. Possible values are incomingconnections.ports,proxy.url,extensions.allowlist,extensions.blocklist,proxy.bypass,guestconfiguration.enabled,extensions.enabled .PARAMETER OutPutType .EXAMPLE Clear-AzureArcNodeConfiguration -ConfigurationName proxy.url -OutPutType JSON #> [CmdletBinding()] Param( [Parameter(Mandatory = $True,HelpMessage = 'Enter the Configuration Name')] [ValidateSet("incomingconnections.ports","proxy.url","extensions.allowlist","extensions.blocklist","proxy.bypass","guestconfiguration.enabled","extensions.enabled")] $ConfigurationName, [Parameter(Mandatory = $True,HelpMessage = 'Enter the output type')] [ValidateSet("JSON", "RAW")] $OutPutType = "JSON" ) Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ If($OutPutType -eq "JSON"){ $Parameters = '& $AZCMAGENTLocation config clear $ConfigurationName -j' } Else{ $Parameters = '& $AZCMAGENTLocation config clear $ConfigurationName' } $SetConfigResults = Invoke-Expression $Parameters Return $SetConfigResults } End{} } Function Get-MSIVersion { <# Source - https://raw.githubusercontent.com/Azure/ArcEnabledServersGroupPolicy/main/EnableAzureArc.ps1 #> Param( [IO.FileInfo]$Path ) $WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer $Database = $windowsInstaller.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $Null,$windowsInstaller, @($path.FullName, 0)) $Query = "SELECT Value FROM Property WHERE Property = 'ProductVersion'" $View = $Database.GetType().InvokeMember( "OpenView", "InvokeMethod", $Null, $database, ($Query) ) $View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null) $Record = $View.GetType().InvokeMember( "Fetch", "InvokeMethod", $Null, $View, $Null ) $Version = ($Record.GetType().InvokeMember( "StringData", "GetProperty", $Null, $record, 1 )) return $Version } Function Download-AzureArcAgent { $ArcAgentURL = "https://aka.ms/AzureConnectedMachineAgent" $MSILocation = "C:\Windows\Temp\AzureConnectedMachineAgent.msi" Invoke-WebRequest -Uri $ArcAgentURL -OutFile $MSILocation } Function Install-AzureArcAgent { <# .Synopsis Installs Azure Arc Agent .DESCRIPTION Installs Azure Arc Agent .EXAMPLE Install-AzureArcAgent #> Begin{ $MSILocation = "C:\Windows\Temp\AzureConnectedMachineAgent.msi" Download-AzureArcAgent $DownloadedVersion = Get-MSIVersion -Path $MSILocation $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ [Version]$InstalledVersion = 0.0.0.0 } Else{ [Version]$InstalledVersion = (Get-AzureArcNodeAgentInformation -OutPutType JSON).Agentversion } } Process{ If([Version]$InstalledVersion -lt [Version]$DownloadedVersion[1]){ $ARCAgentInstallation = (Start-Process -FilePath msiexec -ArgumentList "/i $MSILocation /qn" -Wait -PassThru).ExitCode If($ARCAgentInstallation -eq 0){ Write-Output -InputObject "Installation succeeded. Exit Code: $ARCAgentInstallation" } Else{ Write-Output -InputObject "Installation failed. Exit Code: $ARCAgentInstallation" } } Else{ "All good. No need to update the agent. Current agent version: $InstalledVersion" } } End{} } Function Save-AzureArcNodeLogs { <# .Synopsis Gathers Azure Arc Agent logs from the local machine for troubleshooting. The logs will be saved on the desktop of the current user .DESCRIPTION Gathers Azure Arc Agent logs from the local machine for troubleshooting. The logs will be saved on the desktop of the current user .EXAMPLE Save-AzureArcNodeLogs #> Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ $Parameters = '& $AZCMAGENTLocation logs -o $env:USERPROFILE\Desktop\AzureConnectedMachineAgentLogs.zip' $Logs = Invoke-Expression $Parameters Return $Logs } End{} } Function Get-AzureArcNodeServiceStatus { <# .Synopsis Prints out local Azure Arc Agent Service Status. .DESCRIPTION Prints out local Azure Arc Agent Service Status. .EXAMPLE Get-AzureArcNodeServiceStatus #> Begin{} Process{ Try{ Get-Service -Name himds -ErrorAction Stop } Catch{ Write-Output -InputObject "Azure Hybrid Instance Metadata Service is not installed" } } End{} } Function Restart-AzureArcNodeService { <# .Synopsis Restarts local Azure Arc Agent Service. .DESCRIPTION Restarts local Azure Arc Agent Service. .EXAMPLE Restart-AzureArcNodeService #> Begin{} Process{ Try{ Restart-Service -Name himds -ErrorAction Stop -Force -Verbose } Catch{ Write-Output -InputObject "Failed to restart Azure Hybrid Instance Metadata Service" } } End{} } Function Test-AzureArcNodeConnection { <# .Synopsis Gathers local Azure Arc Agent Service status. .DESCRIPTION Gathers local Azure Arc Agent Service status. .EXAMPLE Test-AzureArcNodeConnection #> Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ Try{ $URL = "http://localhost:40342/agentstatus" $ServiceStatus = (Invoke-WebRequest -Uri $URL -UseBasicParsing -ErrorAction STOP).Content | ConvertFrom-Json $ServicestatusHash = [ordered]@{} $ServiceStatus.psobject.properties | Sort-Object -Property Name | ForEach-Object { $ServicestatusHash[$((Get-Culture).TextInfo.ToTitleCase($PSItem.Name))] = $PSItem.Value } Return $ServicestatusHash } Catch{ $Error[0] } } End{} } Function Get-AzureArcNodeAgentConfigurationFileContent { <# .Synopsis Prints out local Azure Arc Agent Service "C:\ProgramData\AzureConnectedMachineAgent\Config\agentconfig.json" file content. .DESCRIPTION Prints out local Azure Arc Agent Service "C:\ProgramData\AzureConnectedMachineAgent\Config\agentconfig.json" file content. .EXAMPLE Get-AzureArcNodeAgentConfigurationFileContent #> Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ Try{ $ConfigurationFileContent = Get-Content -Raw -Path "C:\ProgramData\AzureConnectedMachineAgent\Config\agentconfig.json" -ErrorAction Stop | ConvertFrom-Json $ConfigurationFileHash = [ordered]@{} $ConfigurationFileContent.psobject.properties | Sort-Object -Property Name | ForEach-Object { $ConfigurationFileHash[$((Get-Culture).TextInfo.ToTitleCase($PSItem.Name))] = $PSItem.Value } Return $ConfigurationFileHash } Catch{ $Error[0] } } End{} } Function Get-AzureArcNodeAgentLocalConfigurationFileContent { <# .Synopsis Prints out local Azure Arc Agent Service "C:\ProgramData\AzureConnectedMachineAgent\Config\localconfig.json" file content. .DESCRIPTION Prints out local Azure Arc Agent Service "C:\ProgramData\AzureConnectedMachineAgent\Config\localconfig.json" file content. .EXAMPLE Get-AzureArcNodeAgentLocalConfigurationFileContent #> Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ Try{ $ConfigurationFileContent = Get-Content -Raw -Path "C:\ProgramData\AzureConnectedMachineAgent\Config\localconfig.json" -ErrorAction Stop | ConvertFrom-Json $ConfigurationFileHash = [ordered]@{} $ConfigurationFileContent.psobject.properties | Sort-Object -Property Name | ForEach-Object { $ConfigurationFileHash[$((Get-Culture).TextInfo.ToTitleCase($PSItem.Name))] = $PSItem.Value } Return $ConfigurationFileHash } Catch{ $Error[0] } } End{} } Function Get-AzureArcNodeAgentInstalledExtensions { <# .Synopsis Prints out local Azure Arc Agent installed exentsions .DESCRIPTION Prints out local Azure Arc Agent installed exentsions .EXAMPLE Get-AzureArcNodeAgentInstalledExtensions #> Begin{ $AZCMAGENTLocation = "C:\Program Files\AzureConnectedMachineAgent\azcmagent.exe" If(!(Test-Path -Path $AZCMAGENTLocation)){ Throw "Azure Arc Agent not installed" } } Process{ Try{ If(Test-Path -Path "C:\ProgramData\GuestConfig\extension_logs"){ $Extensions = Get-ChildItem -Path "C:\ProgramData\GuestConfig\extension_logs" foreach($Extension in $Extensions){ If(Test-Path "$($Extension.FullName)\state.json"){ $ExtensionData = Get-Content -Raw -Path "$($Extension.FullName)\state.json" -ErrorAction Stop | ConvertFrom-Json $ExtensionData } } } Else{ Write-Output -InputObject "No extensions installed yet." } } Catch{ $Error[0] } } End{} } |