Passing variable values to helper functions

This topic contains 1 reply, has 1 voice, and was last updated by  Janis Berzins 1 year, 10 months ago.

  • Author
    Posts
  • #31708

    Janis Berzins
    Participant

    I have created a custom DSC module with few helper functions and it is not working as expected

    While writing the script I used hard coded variable values (default values) for my helper functions. After my tests I removed the the default values and my DSC resource stopped working only because helper functions did not have the variable values.

    How do I pass the variable values to helper functions?

    DSC config

    
    configuration Name
    {
       
    
        Import-DscResource -module OctopusProjectsDSC
        node ip-10-70-1-229
        {
            # Call Resource Provider
    
             OctopusProjects AppDevProjects
            {
                OctopusURL = "http://octopus-server"
    		    OctopusAPIKey = "API-someAPIkey"
    		    ProjectTR = "app-server"
    		    ProjectEnv = "DEV"
            }
    
        }
    }
    
    
    

    my psm1:

    
    function Get-TargetResource
    {
    	[CmdletBinding()]
    	[OutputType([System.Collections.Hashtable])]
    	param
    	(
    		[parameter(Mandatory = $true)]
    		[System.String]
    		$OctopusURL
    	)
    
    	#Write-Verbose "Use this cmdlet to deliver information about command processing."
    
    	#Write-Debug "Use this cmdlet to write debug information while troubleshooting."
    
    
    	
    	$returnValue = @{
    		OctopusURL = [System.String]$OctopusURL
    		OctopusAPIKey = [System.String]$OctopusAPIKey
    		ProjectTR = [System.String]$ProjectTR
    		ProjectEnv = [System.String]$ProjectEnv
    	}
    
    	$returnValue
    
    }
    
    
    function Set-TargetResource
    {
    	[CmdletBinding()]
    	param
    	(
    		[parameter(Mandatory = $true)]
    		[System.String]
    		$OctopusURL,
    
    		[System.String]
    		$OctopusAPIKey,
    
    		[System.String]
    		$header,
    
    		[System.String]
    		$ProjectTR,
    
    		[System.String]
    		$ProjectEnv
    	)
    
    	#Write-Verbose "Use this cmdlet to deliver information about command processing."
    
    	#Write-Debug "Use this cmdlet to write debug information while troubleshooting."
    
    	#Include this line if the resource requires a system reboot.
    	#$global:DSCMachineStatus = 1
        
    
    
        Begin
        {
            $IISExistingWebSites = Get-Website | Select-Object -ExpandProperty name
            New-Alias -Name Octo -Value "C:\Temp\OctopusTools\Octo.exe" -Force
            $ProjectsList = Get-OctopusProjectsIISWebSiteNames | Select-Object -ExpandProperty Octopus.Action.IISWebSite.WebSiteName
            $IISProjectID =  Get-IISWebSiteNamesandProjects
            $ProjectIDIISnames= Get-ProjectIDandNames
            }
            Process
            {
            $websites = @()
    	    foreach ($website in $IISExistingWebSites) {
    	        if ($website -ne "Default Web Site"){
    			        $websites += $website
    		        }
            }
    
    	    #### Finds out the missing projects###
    	    Write-Verbose "Comparing project list" -Verbose
            $ProjectsMissing = Compare-Object $ProjectsList $websites | Where  SideIndicator -EQ "< =" | Select-Object -ExpandProperty InputObject
            If ($ProjectsMissing -gt 0) {
    					
    	    Write-Verbose "Setting Up the following Projects: $ProjectsMissing" -Verbose
                        
            foreach ($OctopusProject in $ProjectsMissing) {
            Write-Verbose "creating Missing project ID and Missing Project Names" -Verbose
    
            $MissingProjectID =  $IISProjectID.get_item($OctopusProject)
            $MissingProjectName = $ProjectIDIISnames.get_item($MissingProjectID)
    
            Write-Verbose "Starting to deploy projects" -Verbose
    
            $OctoAlias = Get-Alias octo |Select-Object -ExpandProperty Definition
    
            Write-Verbose "Set location to C:\Temp\OctopusTools\" -Verbose
    
            Push-Location "C:\Temp\OctopusTools\"
    
            Invoke-AndAssert { & .\Octo.exe deploy-release --project $MissingProjectName --version=latest --deployto $ProjectEnv --specificmachines=$env:computername --server $OctopusURL --apiKey $OctopusAPIKey}
            }
            
            } Else {Write-Verbose -Message 'Nothing to deploy' -Verbose}
    
    
        }
        End
        {
            Start-Sleep -Seconds 5
    
    	    $IISWebsites = Get-Website | Select-Object -ExpandProperty name
    					
    	    Write-Verbose "Websites/Projects running on this node: $IISWebsites "
        }
    
    
    
    
    
    
    
    
    }
    
    
    function Test-TargetResource
    {
    	[CmdletBinding()]
    	[OutputType([System.Boolean])]
    	param
    	(
    		[parameter(Mandatory = $true)]
    		[System.String]
    		$OctopusURL,
    
    		[System.String]
    		$OctopusAPIKey,
    
    		[System.String]
    		$header,
    
    		[System.String]
    		$ProjectTR,
    
    		[System.String]
    		$ProjectEnv
    	)
    
    	#Write-Verbose "Use this cmdlet to deliver information about command processing."
    
    	#Write-Debug "Use this cmdlet to write debug information while troubleshooting."
    
    
    	
            Write-Verbose -Message 'Testing if octo.exe exist'
            If (!(Test-Path -Path "C:\Temp\OctopusTools\Octo.exe")) {
            Write-Verbose -Message 'Octo.exe tool does not exist' -Verbose
            return $False} else {
            Write-Verbose 'Octo.exe exists'}
            $IISExistingWebSites = Get-Website | Select-Object -ExpandProperty name
            New-Alias -Name Octo -Value "C:\Temp\OctopusTools\Octo.exe" -Force
            $ProjectsList = Get-OctopusProjectsIISWebSiteNames | Select-Object -ExpandProperty Octopus.Action.IISWebSite.WebSiteName
            $IISProjectID =  Get-IISWebSiteNamesandProjects
            $ProjectIDIISnames= Get-ProjectIDandNames
    
    
                        
            $websites = @()
    	    foreach ($website in $IISExistingWebSites) {
    	        if ($website -ne "Default Web Site"){
    			        $websites += $website
    		        }
            }
             #### Finds out the missing projects###
    	    Write-Verbose "Comparing project list 2" -Verbose
            $ProjectsMissing = Compare-Object $ProjectsList $websites | Where  SideIndicator -EQ "<=" | Select-Object -ExpandProperty InputObject
            Write-Verbose -Message "projects missing $ProjectsMissing"
    
            Write-Verbose -Message 'tested if something missing01'
    
            If ($ProjectsMissing -gt 0) {return $false}
            else {Write-Verbose -Message 'Node has all necesary projects running. Nothing to deploy'
            return $true}
    
            Write-Verbose -Message 'tested if something missing'
    
    }
    
    
    Export-ModuleMember -Function *-TargetResource
    
    
    
    
    
    ## builds a hastable of environment names and IDs
    
    
    
    function Get-EnvironmentID
    {
        [CmdletBinding()]
        [Alias()]
        [OutputType([Hashtable])]
        Param
        (
            # Octopus URL
            [Parameter(Mandatory=$false)]
            [string]$OctopusURL = "http://octopus",
    
            # Octopus API-Key
            [Parameter(Mandatory=$false)]
            [string]$OctopusAPIKey = "API-key" 
    
        )
    
    	Write-Verbose -Message 'Building environment name and environment ID hash table' -Verbose
        
    
        $Environments = Invoke-RestMethod $OctopusURL/api/environments -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey } | Select -ExpandProperty Items
    
        $Environments | Select-Object Name, ID | % { $EnvironmentHashTable = @{} } { $EnvironmentHashTable[$_.Name] = $_.ID}
    
        return $EnvironmentHashTable
    }
    
    #Get-EnvironmentID
    
    #$EnvironmentID.get_item("PROD")
    
    function Get-EnvironmentTarget
    {
        [CmdletBinding()]
        [Alias()]
        [OutputType([Hashtable])]
        Param
        (
            # Octopus URL
            [Parameter(Mandatory=$false)]
            [string]$OctopusURL = "http://octopus",
    
            # Octopus API-Key
            [Parameter(Mandatory=$false)]
            [string]$OctopusAPIKey = "API-key"
            
            
    
        )
    
    Write-Verbose -Message 'Building environment name and Project ID target roles hash table' -Verbose
    
    Write-verbose "Retrieving projects"
    $Projects = Invoke-RestMethod $OctopusURL/api/projects -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey } | Select -ExpandProperty Items
    Write-verbose "Building deployment process API list"
    $DeploymentProcesses=$Projects.links.DeploymentProcess
    
    #Write-Host "Building project ID and target roles hash table"
    foreach ($Processes in $DeploymentProcesses) {
    
    
    $ProjectNameTargetHash = @{}
    
    $ProjectID = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Processes" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }) | select -expand ProjectID
    
    $ProjectTargetRole = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Processes" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }).Steps.Properties | select -expand Octopus.Action.TargetRoles -First 1
    
    $ProjectNameTargetHash.Add($ProjectID, $ProjectTargetRole)
    
    $ProjectTargerHash += $ProjectNameTargetHash
    
        
    }
    
    
    
    # Project ID targer Hash tabale 
    return $ProjectTargerHash
    }
    
    #Get-EnvironmentTarget
    
    
    
    
    
    function Get-ProjectIDEnvironment
    {
        [CmdletBinding()]
        [Alias()]
        [OutputType([Hashtable])]
        Param
        (
            # Octopus URL
            [Parameter(Mandatory=$false)]
            [string]$OctopusURL = "http://octopus",
    
            # Octopus API-Key
            [Parameter(Mandatory=$false)]
            [string]$OctopusAPIKey = "API-key"
    		
            
            
    
        )
    
    Write-Verbose -Message 'Building project ID and environment ID hash table' -Verbose
    
    
    $Projects = Invoke-RestMethod $OctopusURL/api/projects -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey } | Select -ExpandProperty Items
    $DeploymentProcesses=$Projects.links.DeploymentProcess
    
    
    foreach ($Processes in $DeploymentProcesses) {
    
    $ProjectNameEnvironmentsHash = @{}
    
    $ProjectID = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Processes" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }) | select -expand ProjectID
    $ProjectEnvironment = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Processes" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }).Steps.Actions.Environments | sort -Unique
    
    $ProjectNameEnvironmentsHash.Add($ProjectID, $ProjectEnvironment)
    
    $ProjectEnvironmentHash += $ProjectNameEnvironmentsHash
        
    }
    
    return $ProjectEnvironmentHash
    
    }
    
    
    #Get-ProjectIDEnvironment
    
    
    
    
    function Get-OctopusProjectsIISWebSiteNames
    {
    
        Param
        (
             # Octopus URL
            [Parameter(Mandatory=$false)]
            [string]$OctopusURL = "http://octopus",
    
            # Octopus API-Key
            [Parameter(Mandatory=$false)]
            [string]$OctopusAPIKey = "API-key",
    
            [Parameter(Mandatory=$false)]
            [string]$ProjectTR = "app-server",
            
            [Parameter(Mandatory=$false)]
            [string]$ProjectEnv = "DEV"
            
            
    
        )
    
        
            $EnvironmentID = Get-EnvironmentID
            $EnvironmentTarget = Get-EnvironmentTarget
            $ProjectIDEnvironment = Get-ProjectIDEnvironment
    
    	    $Projects = Invoke-RestMethod $OctopusURL/api/projects -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey } | Select -ExpandProperty Items
            $DeploymentProcesses=$Projects.links.DeploymentProcess
    
    foreach ($Processes in $DeploymentProcesses) {
    
    
    
    $ProjectID = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Processes" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }) | select -expand ProjectID
    $Projects = Invoke-RestMethod $OctopusURL/api/projects -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey } | Select -ExpandProperty Items
    $DeploymentProcesses=$Projects.links.DeploymentProcess
    
    If ($ProjectIDEnvironment.Item($ProjectID) -contains $EnvironmentID.Item($ProjectEnv) -and $EnvironmentTarget.Item($ProjectID) -contains $ProjectTR ) { 
    
    (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Processes" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }).Steps.Actions.Properties | select Octopus.Action.IISWebSite.WebSiteName
    
    } #else {write-host "$IISWebSiteName will be skipped"}
    
    
    }
    
    
    
    
    
    }
    
    
    function Get-IISWebSiteNamesandProjects
    {
        [CmdletBinding()]
        [Alias()]
        #[OutputType([int])]
        Param
        (
             # Octopus URL
            [Parameter(Mandatory=$false)]
            [string]$OctopusURL = "http://octopus",
    
            # Octopus API-Key
            [Parameter(Mandatory=$false)]
            [string]$OctopusAPIKey = "API-key",
    
            [Parameter(Mandatory=$false)]
            [string]$ProjectTR = "app-server",
            
            [Parameter(Mandatory=$false)]
            [string]$ProjectEnv = "DEV"
        )
    
        Begin
        {
        $EnvironmentIDHash = Get-EnvironmentID
    
        }
        Process
        {
        $Projects = Invoke-RestMethod $OctopusURL/api/projects/all -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey } 
        $ProjectList=$Projects.name
        $DeploymentProcesses = $Projects.links.DeploymentProcess
    
        Write-Verbose 'starting foreach loop'-Verbose
    
        foreach ($Process in $DeploymentProcesses){
        
    
                $Steps=Invoke-RestMethod $OctopusURL/$Process -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey }  | Select-Object -ExpandProperty Steps
                
                $StepRole = $steps.properties | Select-Object -ExpandProperty Octopus.Action.TargetRoles | Select-Object -First 1 -Verbose
                
                $Actions=Invoke-RestMethod $OctopusURL/$Process -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey }  | Select-Object -ExpandProperty Steps
    
                $Environments = $Actions.actions.environments | Sort-Object -Unique
                
                Write-Verbose 'foreach loop before if statement' 
    
                                if ($Environments -contains  $EnvironmentIDHash.get_item($ProjectEnv) -and $StepRole -contains $ProjectTR ) {
                                $table = @{}
                
                                Write-Verbose 'running if statement'
    
                                $IISName = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Process" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }).Steps.Actions.Properties | select Octopus.Action.IISWebSite.WebSiteName
    
                                $WebSiteName = $IISName | Select-Object -ExpandProperty Octopus.Action.IISWebSite.WebSiteName
    
                                #Write-Output $WebSiteName
    
                                $ProjectID = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Process" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }).ProjectID
    
                                #Write-Output $ProjectID
                
                
                                $table.add($WebSiteName, $ProjectID)
                                $Table01 += $table
                                
                                Continue
                
    
                                } else { Write-Verbose  'Failed' -Verbose  }
    
    
              # $Table01 |  Write-Output
    
          
    
    
                #return $Table01
    
    
        }
    
        return $Table01 
    
        }
    
    }
    
    
    
    
    
    
    function Get-ProjectIDandNames
    {
        [CmdletBinding()]
        [Alias()]
        [OutputType([Hashtable])]
        Param
        (
            # Octopus URL
            [Parameter(Mandatory=$false)]
            [string]$OctopusURL = "http://octopus",
    
            # Octopus API-Key
            [Parameter(Mandatory=$false)]
            [string]$OctopusAPIKey = "API-key"
            
    
        )
    
    Write-Verbose -Message 'Building project ID and Project name hash table' -Verbose
    
    
    $Projects = Invoke-RestMethod $OctopusURL/api/projects -Headers @{ "X-Octopus-ApiKey" = $OctopusAPIKey } | Select -ExpandProperty Items
    $SelfProjects=$Projects.links.self
    
    
    foreach ($Self in $SelfProjects) {
    
    $ProjectIDNameHash = @{}
    
    $ProjectID = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Self" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }) | select -expand ID
    $ProjectName = (Invoke-RestMethod -Method Get -Uri "$OctopusURL/$Self" -Header @{ "X-Octopus-ApiKey" = $OctopusAPIKey }) | select -expand Name
    
    $ProjectIDNameHash.Add($ProjectID, $ProjectName)
    
    $ProjectIDNameHashTable += $ProjectIDNameHash
        
    }
    
    return $ProjectIDNameHashTable
    
    }
    
    #Get-ProjectIDandNames
    
    
    
    
    
    
    function Set-OctopusProjects
    {
        [CmdletBinding()]
        [OutputType([int])]
        Param
        (
             # Octopus URL
            [Parameter(Mandatory=$false)]
            [string]$OctopusURL = "http://octopus",
    
            # Octopus API-Key
            [Parameter(Mandatory=$false)]
            [string]$OctopusAPIKey = "API-key",
    
            [Parameter(Mandatory=$false)]
            [string]$ProjectTR = "app-server",
            
            [Parameter(Mandatory=$false)]
            [string]$ProjectEnv = "DEV"
        )
    
        Begin
        {
            $IISExistingWebSites = Get-Website | Select-Object -ExpandProperty name
            New-Alias -Name Octo -Value "C:\Temp\OctopusTools\Octo.exe" -Force
            $ProjectsList = Get-OctopusProjectsIISWebSiteNames | Select-Object -ExpandProperty Octopus.Action.IISWebSite.WebSiteName
            $IISProjectID =  Get-IISWebSiteNamesandProjects
            $ProjectIDIISnames= Get-ProjectIDandNames
            }
            Process
            {
            $websites = @()
    	    foreach ($website in $IISExistingWebSites) {
    	        if ($website -ne "Default Web Site"){
    			        $websites += $website
    		        }
            }
    
    	    #### Finds out the missing projects###
    	    Write-Verbose "Comparing project list" -Verbose
            $ProjectsMissing = Compare-Object $ProjectsList $websites | Where  SideIndicator -EQ "<=" | Select-Object -ExpandProperty InputObject
            If ($ProjectsMissing -gt 0) {
    					
    	    Write-Verbose "Setting Up the following Projects: $ProjectsMissing" -Verbose
                        
            foreach ($OctopusProject in $ProjectsMissing) {
    
            $MissingProjectID =  $IISProjectID.get_item($OctopusProject)
            $MissingProjectName = $ProjectIDIISnames.get_item($MissingProjectID)
    
            Invoke-AndAssert { & .\Octo.exe deploy-release --project $MissingProjectName --version=latest --deployto $ProjectEnv --specificmachines=$env:computername --server $OctopusURL --apiKey $OctopusAPIKey}
            }
    	    $IISWebsites = Get-Website | Select-Object -ExpandProperty name
    					
    	    Write-Verbose "Websites/Projects running on this node: $IISWebsites "
            } Else {Write-Verbose -Message 'Nothing to deploy' -Verbose}
    
    
        }
        End
        {
        }
    }
    
    
    function Invoke-AndAssert {
        param ($block) 
      
        & $block | Write-Verbose
        if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne $null) 
        {
            throw "Command returned exit code $LASTEXITCODE"
        }
    }
    
    
  • #31715

    Janis Berzins
    Participant

    I have figured out it myself. I was calling the helper functions without variables from other functions. Lesson learned 🙂

    Maybe someone can give me an advice on how to speed up the Test- and Set- process? How to do Invoke-RestMethod once in Test and keep it in memory for Set process?

You must be logged in to reply to this topic.