IGNORE/CfnResource.ps1

<#
.SYNOPSIS
Resource properties are additional options that you can specify for a resource.
 
.DESCRIPTION
The required Resources section declare the AWS resources that you want as part of your stack, such as an Amazon EC2 instance or an Amazon S3 bucket. You must declare each resource separately; however, you can specify multiple resources of the same type.
 
 
 
For example, for each Amazon EC2 instance, you must specify an AMI ID for that instance. You declare the AMI ID as a property of the instance.
 
You can add a Resource using either the generic Resource declaration or a strongly-typed Resource-specific declaration. For the latter, you can specify any of the defined Properties as cmdlet parameters, however you are restricted to only specifying literal values of the appropriate type and conforming to the associated parameter validation rules.
 
However, each strongly-typed Resource, and the generic Resource declartion support an optional Properties scriptblock which allows you to specify one or more Property declarations which can resolve to a CloudFormation runtime-evaluated Function call.
 
.PARAMETER Name
The name of a Property to assign a value to for the parent Resource.
 
.PARAMETER Value
The value to assign to the named Property for the parent Resource.
 
Property values can be literal strings, lists of strings, booleans, Parameter references, Pseudo references, or the value returned by a Function. When a Property value is a literal string, the value is enclosed in double quotes.
 
Note that you can conditionally create a Resource by associating a condition with it. You must define the Condition in the Conditions section of the Template.
 
.LINK
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html
#>


$AWSCFN_RESOURCE_TYPES = 'a','b','c'

function Add-CfnResource {
    [CmdletBinding(DefaultParameterSetName="Type")]
    param(
        [Parameter(Mandatory,Position=0)]
        [string]$Name,
       #[Parameter(Mandatory,ParameterSetName="Type",Position=1)]
       #[ValidateSet(...)]
       #[string]$Type,
        [Parameter(Mandatory,ParameterSetName="RawType",Position=1)]
        [string]$RawType,
        [System.Collections.IDictionary]$Properties,
        [scriptblock]$PropertiesBlock
    )


    ## Inspiration:
    ## https://blogs.technet.microsoft.com/pstips/2014/06/09/dynamic-validateset-in-a-dynamic-parameter/
    DynamicParam {
            $ParameterName = 'Type'
            $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]

            $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParameterAttribute.Mandatory = $true
            $ParameterAttribute.ParameterSetName = 'Type'
            $ParameterAttribute.Position = 1
            $AttributeCollection.Add($ParameterAttribute)

            $ParameterAttribute = New-Object System.Management.Automation.ValidateSetAttribute($AWSCFN_RESOURCE_TYPES)
           #$ParameterAttribute.ValidValues = $AWSCFN_RESOURCE_TYPES
            $AttributeCollection.Add($ValidateSetAttribute)

            # Create and return the dynamic parameter
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
            return $RuntimeParameterDictionary
    }

    begin {
        #$tResources = [System.Collections.IDictionary](Get-Variable -Name "tResources" -ValueOnly)
        #if (-not $tResources) {
        # throw "Template Resources collection is not in scope"
        #}
        #
        #if ($tResources.Contains($Name)) {
        # throw "Duplicate Resource name [$Name]"
        #}

        if (-not $RawType) {
            $Type = $PsBoundParameters[$ParameterName]
        }
        else {
            $Type = $RawType
        }
    }

    process {
        $r = @{ Type = $Type }
        $rProperties = [ordered]@{}

        if ($Properties -and $Properties.Count) {
            foreach ($pk in $Properties.Keys) {
                $rProperties = $Properties[$pk]
            }
        }
        if ($PropertiesBlock) {
            $PropertiesBlock.Invoke()
        }

        @{ $Name = $r }
            
        #$tResources.Add($Name, $r)
    }

}
Set-Alias -Name Resource -Value Add-CfnResource