Skip to content

Commit 6ebd058

Browse files
Merge pull request #95 from PowershellFrameworkCollective/development
2.2.6.65
2 parents 8a1b9d7 + f643fe3 commit 6ebd058

File tree

13 files changed

+391
-17
lines changed

13 files changed

+391
-17
lines changed

PSModuleDevelopment/PSModuleDevelopment.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
RootModule = 'PSModuleDevelopment.psm1'
55

66
# Version number of this module.
7-
ModuleVersion = '2.2.6.62'
7+
ModuleVersion = '2.2.6.65'
88

99
# ID used to uniquely identify this module
1010
GUID = '37dd5fce-e7b5-4d57-ac37-832055ce49d6'

PSModuleDevelopment/changelog.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
2-
##
2+
## 2.2.6.65 (May 2nd, 2019)
3+
- New: Template: AzureFunctionRest - creates an azure function designed for rest API trigger.
4+
- Upd: Template: PSFProject added Azure Functions Project CI/CD integration.
5+
- Upd: Invoke-PSMDTemplate supports `-Encoding` parameter, defaulting to utf8 with BOM.
6+
7+
## 2.2.6.62 (April 30th, 2019)
38
- New: Get-PSMDArgumentCompleter - Lists registered argument completers on PS5+
49
- New: Template: PSFLoggingProvider - Creates a custom logfile logging provider for module specific logging.
510
- Upd: Template: PSFTest - Adding test against module tags with whitespace

PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
Skip automatic folder creation for project templates.
3939
By default, this command will create a folder to place files&folders in when creating a project.
4040
41+
.PARAMETER Encoding
42+
The encoding to apply to text files.
43+
The default setting for this can be configured by updating the 'PSFramework.Text.Encoding.DefaultWrite' configuration setting.
44+
The initial default value is utf8 with BOM.
45+
4146
.PARAMETER Parameters
4247
A Hashtable containing parameters for use in creating the template.
4348
@@ -75,15 +80,15 @@
7580
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSPossibleIncorrectUsageOfAssignmentOperator", "")]
7681
[CmdletBinding(SupportsShouldProcess = $true)]
7782
param (
78-
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Template')]
79-
[PSModuleDevelopment.Template.TemplateInfo[]]
80-
$Template,
81-
8283
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'NameStore')]
8384
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'NamePath')]
8485
[string]
8586
$TemplateName,
8687

88+
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Template')]
89+
[PSModuleDevelopment.Template.TemplateInfo[]]
90+
$Template,
91+
8792
[Parameter(ParameterSetName = 'NameStore')]
8893
[string]
8994
$Store = "*",
@@ -100,6 +105,9 @@
100105
[string]
101106
$Name,
102107

108+
[PSFEncoding]
109+
$Encoding = (Get-PSFConfigValue -FullName 'PSFramework.Text.Encoding.DefaultWrite'),
110+
103111
[switch]
104112
$NoFolder,
105113

@@ -176,6 +184,9 @@
176184
[string]
177185
$OutPath,
178186

187+
[PSFEncoding]
188+
$Encoding,
189+
179190
[bool]
180191
$NoFolder,
181192

@@ -237,7 +248,7 @@
237248
{
238249
foreach ($child in $templateData.Children)
239250
{
240-
Write-TemplateItem -Item $child -Path $OutPath -ParameterFlat $Parameters -ParameterScript $scriptParameters -Raw $Raw
251+
Write-TemplateItem -Item $child -Path $OutPath -Encoding $Encoding -ParameterFlat $Parameters -ParameterScript $scriptParameters -Raw $Raw
241252
}
242253
if ($Raw -and $templateData.Scripts.Values)
243254
{
@@ -272,7 +283,7 @@
272283

273284
foreach ($child in $templateData.Children)
274285
{
275-
Write-TemplateItem -Item $child -Path $newFolder.FullName -ParameterFlat $Parameters -ParameterScript $scriptParameters -Raw $Raw
286+
Write-TemplateItem -Item $child -Path $newFolder.FullName -Encoding $Encoding -ParameterFlat $Parameters -ParameterScript $scriptParameters -Raw $Raw
276287
}
277288

278289
#region Write Config File (Raw)
@@ -308,7 +319,7 @@
308319
}
309320

310321
$configFile = Join-Path $newFolder.FullName "PSMDTemplate.ps1"
311-
Set-Content -Path $configFile -Value $optionsTemplate -Encoding UTF8
322+
Set-Content -Path $configFile -Value $optionsTemplate -Encoding ([PSFEncoding]'utf-8').Encoding
312323
}
313324
#endregion Write Config File (Raw)
314325
}
@@ -327,6 +338,9 @@
327338
[string]
328339
$Path,
329340

341+
[PSFEncoding]
342+
$Encoding,
343+
330344
[hashtable]
331345
$ParameterFlat,
332346

@@ -373,7 +387,7 @@
373387
$text = $text -replace "$($identifier)!$([regex]::Escape($param))!$($identifier)", $ParameterScript[$param]
374388
}
375389
}
376-
[System.IO.File]::WriteAllText($destPath, $text)
390+
[System.IO.File]::WriteAllText($destPath, $text, $Encoding)
377391
}
378392
else
379393
{
@@ -417,23 +431,19 @@
417431
{
418432
if ($PSCmdlet.ShouldProcess($item, "Invoking template"))
419433
{
420-
try { Invoke-Template -Template $item -OutPath $resolvedPath.ProviderPath -NoFolder $NoFolder -Parameters $Parameters.Clone() -Raw $Raw -Silent $Silent }
434+
try { Invoke-Template -Template $item -OutPath $resolvedPath.ProviderPath -NoFolder $NoFolder -Encoding $Encoding -Parameters $Parameters.Clone() -Raw $Raw -Silent $Silent }
421435
catch { Stop-PSFFunction -Message "Failed to invoke template $($item)" -EnableException $EnableException -ErrorRecord $_ -Target $item -Tag 'fail', 'template', 'invoke' -Continue }
422436
}
423437
}
424438
foreach ($item in $templates)
425439
{
426440
if ($PSCmdlet.ShouldProcess($item, "Invoking template"))
427441
{
428-
try { Invoke-Template -Template $item -OutPath $resolvedPath.ProviderPath -NoFolder $NoFolder -Parameters $Parameters.Clone() -Raw $Raw -Silent $Silent }
442+
try { Invoke-Template -Template $item -OutPath $resolvedPath.ProviderPath -NoFolder $NoFolder -Encoding $Encoding -Parameters $Parameters.Clone() -Raw $Raw -Silent $Silent }
429443
catch { Stop-PSFFunction -Message "Failed to invoke template $($item)" -EnableException $EnableException -ErrorRecord $_ -Target $item -Tag 'fail', 'template', 'invoke' -Continue }
430444
}
431445
}
432446
}
433-
end
434-
{
435-
436-
}
437447
}
438448

439449
if (-not (Test-Path Alias:\imt)) { Set-Alias -Name imt -Value Invoke-PSMDTemplate }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
param (
2+
$Path
3+
)
4+
5+
New-PSMDTemplate -FilePath "$PSScriptRoot\þnameþ.ps1" -TemplateName AzureFunctionRest -OutPath $Path -Description "Template for an Azure Function with Rest Trigger" -Author "Friedrich Weinmann" -Tags 'function', 'file', 'azure'
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
function þnameþ
2+
{
3+
<#
4+
.SYNOPSIS
5+
Insert Synopsis
6+
7+
.DESCRIPTION
8+
Insert Description
9+
10+
.PARAMETER Request
11+
Contains the Request Information the Azure Function was called with.
12+
Effectively the parameters.
13+
14+
.PARAMETER TriggerMetadata
15+
Azure Functions Specific Vodoo. Don't touch unless you know what you do.
16+
17+
.EXAMPLE
18+
PS C:\> Invoke-RestMethod '<insert function uri>'
19+
20+
Invokes the Azure function without any parameter.
21+
#>
22+
[CmdletBinding()]
23+
param (
24+
$Request,
25+
26+
$TriggerMetadata
27+
)
28+
29+
begin
30+
{
31+
#region Convert input parameters from Azure Functions
32+
if ($env:Functions_EXTENSION_VERSION)
33+
{
34+
$PSBoundParameters.Clear()
35+
$PSBoundParameters = Convert-AzureFunctionParameter -Request $Request
36+
}
37+
#endregion Convert input parameters from Azure Functions
38+
}
39+
process
40+
{
41+
if ($failed)
42+
{
43+
Write-AzureFunctionOutput -Value 'Failed to execute successfully!' -Status InternalServerError
44+
return
45+
}
46+
}
47+
end
48+
{
49+
Write-AzureFunctionOutput -Value $results -Serialize
50+
return
51+
}
52+
}

templates/PSFProject/PSMDTemplate.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@{
22
TemplateName = 'PSFProject'
3-
Version = "1.1.1.0"
3+
Version = "1.2.1.0"
44
AutoIncrementVersion = $true
55
Tags = 'module','psframework'
66
Author = 'Friedrich Weinmann'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"version": "2.0"
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"IsEncrypted": false,
3+
"Values": {
4+
"FUNCTIONS_WORKER_RUNTIME": "powershell",
5+
"AzureWebJobsStorage": "--connection string for storage account---"
6+
}
7+
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<#
2+
This is the globl profile file for the Azure Function.
3+
This file will have been executed first, before any function runs.
4+
Use this to create a common execution environment,
5+
but keep in mind that the profile execution time is added to the function startup time for ALL functions.
6+
#>
7+
8+
$global:functionStatusCode = [System.Net.HttpStatusCode]::OK
9+
function Convert-AzureFunctionParameter
10+
{
11+
<#
12+
.SYNOPSIS
13+
Extracts the parameters passed into the rest method.
14+
15+
.DESCRIPTION
16+
Extracts the parameters passed into the rest method of an Azure Function.
17+
Returns a hashtable, similar to what would be found on a $PSBoundParameters variable.
18+
19+
.PARAMETER Request
20+
The request to process
21+
22+
.EXAMPLE
23+
PS C:\> Convert-AzureFunctionParameter -Request $request
24+
25+
Converts the $request object into a regular hashtable.
26+
#>
27+
[CmdletBinding()]
28+
param (
29+
$Request
30+
)
31+
32+
$parameters = @{ }
33+
34+
foreach ($key in $Request.Query.Keys)
35+
{
36+
# Do NOT include the authentication key
37+
if ($key -eq 'code') { continue }
38+
$parameters[$key] = $Request.Query.$key
39+
}
40+
foreach ($key in $Request.Body.Keys)
41+
{
42+
$parameters[$key] = $Request.Body.$key
43+
}
44+
45+
$parameters
46+
}
47+
48+
function Set-AzureFunctionStatus
49+
{
50+
<#
51+
.SYNOPSIS
52+
Sets the return status of the function.
53+
54+
.DESCRIPTION
55+
Sets the return status of the function.
56+
By default, the status is "OK"
57+
58+
.PARAMETER Status
59+
Set the HTTP status for the return from Azure Functions.
60+
Any status other than OK will cause a terminating error if run outside of Azure Functions.
61+
62+
.EXAMPLE
63+
PS C:\> Set-AzureFunctionStatus -Status BadRequest
64+
65+
Updates the status to say "BadRequest"
66+
#>
67+
[CmdletBinding()]
68+
param (
69+
[Parameter(Mandatory = $true)]
70+
[System.Net.HttpStatusCode]
71+
$Status
72+
)
73+
74+
$global:functionStatusCode = $Status
75+
}
76+
77+
function Write-AzureFunctionOutput
78+
{
79+
<#
80+
.SYNOPSIS
81+
Write output equally well from Azure Functions or locally.
82+
83+
.DESCRIPTION
84+
Write output equally well from Azure Functions or locally.
85+
When calling this command, call return straight after it.
86+
Use Write-AzureFunctionStatus first if an error should be returned, then specify an error text here.
87+
88+
.PARAMETER Value
89+
The value data to return.
90+
Either an error message
91+
92+
.PARAMETER Serialize
93+
Return the output object as compressed clixml string.
94+
You can use ConvertFrom-PSFClixml to restore the object on the recipient-side.
95+
96+
.EXAMPLE
97+
PS C:\> Write-AzureFunctionOutput -Value $result
98+
99+
Writes the content of $result as output.
100+
101+
.EXAMPLE
102+
PS C:\> Write-AzureFunctionOutput -Value $result -Serialize
103+
104+
Writes the content of $result as output.
105+
If called from Azure Functions, it will convert the output as compressed clixml string.
106+
107+
#>
108+
[CmdletBinding()]
109+
param (
110+
[Parameter(Mandatory = $true)]
111+
$Value,
112+
113+
[switch]
114+
$Serialize,
115+
116+
[System.Net.HttpStatusCode]
117+
$Status
118+
)
119+
120+
if ($PSBoundParameters.ContainsKey('Status'))
121+
{
122+
Set-AzureFunctionStatus -Status $Status
123+
}
124+
125+
# If not in function, just return value
126+
if (-not $env:Functions_EXTENSION_VERSION)
127+
{
128+
if ($global:functionStatusCode -ne [System.Net.HttpStatusCode]::OK)
129+
{
130+
throw $Value
131+
}
132+
return $Value
133+
}
134+
135+
if ($Serialize)
136+
{
137+
$Value = $Value | ConvertTo-PSFClixml
138+
}
139+
140+
Push-OutputBinding -Name Response -Value (
141+
[HttpResponseContext]@{
142+
StatusCode = $global:functionStatusCode
143+
Body = $Value
144+
}
145+
)
146+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Azure Function Resources
2+
3+
This folder is used to store Azure Function specific meta data and resources.
4+
5+
This folder is also used to allow the user to easily create a custom function-specific configuration, for exanmple in order to change the trigger settings.
6+
7+
To specify custom, 'Per Function' configuration json, just place the desired configuration file as 'functionname.json' into this folder (it does not matter if it is the PowerShell function name or the condensed version used for publishing on Azure).

0 commit comments

Comments
 (0)