ISEPSProject.psm1

<#
.Synopsis
   Remove source files from the .psproj file.
.DESCRIPTION
   This process will remove specified files from the project file, and create a backup in the -streams section of the file.
   10 backups will be kept and can be listed with Get-PowershellProjectBackup function.
.EXAMPLE
PS> Get-PowershellProject -ProjectFile .\ISEPSProject.psproj
 
Name Value
---- -----
Remove-SourceFromPowershellProject.ps1 @{FileName=Remove-SourceFromPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Clean-PowershellProject.ps1 @{FileName=Clean-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Open-PowershellProject.ps1 @{FileName=Open-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Get-PowershellProjectBackup.ps1 @{FileName=Get-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj; IncludeInBuild=False}
Compare-PowershellProjectBackup.ps1 @{FileName=Compare-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj Backup; IncludeInBuild=False}
Get-PowershellProject.ps1 @{FileName=Get-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Add-SourceToPowershellProject.ps1 @{FileName=Add-SourceToPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Create-PowershellProject.ps1 @{FileName=Create-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
 
 
PS> Remove-SourceFromPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile .\Add-SourceToPowershellProject.ps1
1 source file(s) have been removed from the project
 
.EXAMPLE
PS> Get-PowershellProject .\ISEPSProject.psproj
 
Name Value
---- -----
Remove-SourceFromPowershellProject.ps1 @{FileName=Remove-SourceFromPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Clean-PowershellProject.ps1 @{FileName=Clean-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Open-PowershellProject.ps1 @{FileName=Open-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Get-PowershellProjectBackup.ps1 @{FileName=Get-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj; IncludeInBuild=False}
Compare-PowershellProjectBackup.ps1 @{FileName=Compare-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj Backup; IncludeInBuild=False}
Get-PowershellProject.ps1 @{FileName=Get-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Create-PowershellProject.ps1 @{FileName=Create-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
 
 
PS> Remove-SourceFromPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile .\Clean-PowershellProject.ps1,.\Compare-PowershellProjectBackup.ps1
2 source file(s) have been removed from the project
.EXAMPLE
PS> Get-PowershellProject .\ISEPSProject.psproj
 
Name Value
---- -----
Remove-SourceFromPowershellProject.ps1 @{FileName=Remove-SourceFromPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Open-PowershellProject.ps1 @{FileName=Open-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Get-PowershellProjectBackup.ps1 @{FileName=Get-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj; IncludeInBuild=False}
Get-PowershellProject.ps1 @{FileName=Get-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Create-PowershellProject.ps1 @{FileName=Create-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
 
PS> Remove-SourceFromPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile (Get-ChildItem -Filter *.ps1).Name
5 source file(s) have been removed from the project
3 source file(s) were not found in the project
#>

function Remove-SourceFromPowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]       
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
        ,
        # Specify the source file name to remove from the project.
        [Parameter(Mandatory=$true,
                   Position=1)]
        [Alias('Source','SourcePath')]
        [ValidateScript({ Test-Path $_ })]
        [string[]]
        $SourceFile
    )

    Begin
    {
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true )
        {
            if ( (Get-PowershellProjectVersion -ProjectFile $ProjectFile).IsLatest -eq $false )
            {
                Update-PowershellProjectVersion -ProjectFile $ProjectFile
            }
            $projectData = Import-Clixml -Path $ProjectFile

            $removedItems = 0
            $notFoundItems = 0
            $keyToRemove = @()
            foreach ($item_SourceFile in $SourceFile)
            {
                if ( $item_SourceFile.StartsWith(".\") )
                {
                    $item_SourceFile = $item_SourceFile.SubString(2)
                }        
           
                if ( $projectData.ContainsKey($item_SourceFile) )
                {
                    $keyToRemove += $item_SourceFile
                } else {
                    $notFoundItems++
                }
            }
            foreach ( $item_keyToRemove in $keyToRemove )
            {
                $projectData.Remove($item_keyToRemove)
                $removedItems++
            }

            Save-PowershellProject -ProjectFile $ProjectFile -ProjectData $projectData
        
            Write-Output "$($removedItems) source file(s) have been removed from the project"
            Write-Output "$($notFoundItems) source file(s) were not found in the project"
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true ) 
        {
        
        }
    }
}
<#
.Synopsis
   Create a single PSM1 file from the PS1 files included in the .psproj file. Because the ISE editor doesn't yet have great code navigation tools, it is easier to have smaller source files opened separately.
.DESCRIPTION
   This process will loop through the Source files and check for the IncludeInBuild flag. Any source file with the include flag will be copied into the {projectname}.psm1 file.
.EXAMPLE
   PS> Build-PowershellProject -ProjectFile ISEPSProject.psproj -Force
 
Build Created.
All functions export: FunctionsToExport = @('Add-SourceToPowershellProject','Build-PowershellProject','Clean-PowershellProject','Close-PowershellProject','Create-PowershellProjec
t','Get-PowershellProject','Open-PowershellProject','Remove-SourceFromPowershellProject','Set-IncludeInBuildFlagForSource','Set-PowershellProjectDefaults','Get-CSVFromStringArray
','Get-PowershellProjectBackupData','Get-PowershellProjectCurrentVersion','Get-PowershellProjectDefaultIncludeInBuild','Get-PowershellProjectDefaultProjectFile','Get-PowershellPr
ojectFunctions','Get-PowershellProjectVersion','Save-PowershellProject','Save-PowershellProjectDefaults','Update-PowershellProjectVersion')
#>

function Build-PowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
        ,
        # Force overwrite of the existing psm1 file.
        [Parameter(Mandatory=$false,
                   Position=1)]
        [switch]
        $Force = $false
        ,
        # Add an NTFS streams version of the existing module content to the newly created psm1 file.
        [Parameter(Mandatory=$false,
                   Position=2)]
        [switch]
        $PerformBackup = $false
    )

    Begin
    {
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true ) 
        {
            if ( (Get-PowershellProjectVersion -ProjectFile $ProjectFile).IsLatest -eq $false )
            {
                Update-PowershellProjectVersion -ProjectFile $ProjectFile
            }
            $projectData = Import-Clixml -Path $ProjectFile
            $newModule = @()

            if ( $ProjectFile.StartsWith(".\") )
            {
                $projectFileKey = $ProjectFile.SubString(2)
            }        
            if ( $projectData.ContainsKey($projectFileKey) )
            {
                $projectData.Remove($projectFileKey)
            }
            if ( $projectData.ContainsKey("ISEPSProjectDataVersion") )
            {
                $projectData.Remove("ISEPSProjectDataVersion")
            }

            $moduleFile = "$((Get-ChildItem $ProjectFile).BaseName).psm1"
            if ( Test-Path $moduleFile )
            {
                $backupModule = Get-Content $moduleFile
            }

            foreach ( $key in $projectData.Keys )
            {
                if ( $projectData[$key].IncludeInBuild -eq $true ) 
                {
                    $newModule += Get-Content -Path $key
                }
            }

            if ( ( Test-Path $moduleFile ) -and ( $Force -eq $true ) )
            {
                $newModule | Out-File -FilePath $moduleFile -Force -Encoding ascii
                if ( ( $PerformBackup -eq $true ) -and ( $backupModule.Length -gt 0 ) )
                {
                    $backupName = (Get-Date).ToString('yyyy-MM-dd_HHmmss')
                    Add-Content -Path $moduleFile -Value $backupModule -Stream $backupName                    
                }
                $functionList = (Get-PowershellProjectFunctions -ProjectFile $ProjectFile -IncludedInBuildOnly | Sort-Object -Property SourceFile,FunctionName).FunctionName
                $functionsToExport = "FunctionsToExport = @($(Get-CSVFromStringArray -StringArray $functionList -SingleQuotes))"
                Write-Output "Build Created."
                Write-Output "All functions export: $($functionsToExport)"
            } else {
                Write-Warning "You must specify the -Force switch in order to over-write the existing psm1 file."
            }

        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true ) 
        {
        
        }
    }
}
<#
.Synopsis
   Close Project Source files if they are saved. This routine was born out of the problem of simply closing ISE with bunches of files/tabs open. Often the next re-open caused ISE to go into recovery mode.
.DESCRIPTION
   This process will loop through the Source files and their associated Project TAB names and close the open files (if they are saved) and close any empty TABs.
 
.EXAMPLE
   Close-PowershellProject -ProjectFile ISEPSProject.psproj
#>

function Close-PowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
    )

    Begin
    {
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true ) 
        {
            if ( (Get-PowershellProjectVersion -ProjectFile $ProjectFile).IsLatest -eq $false )
            {
                Update-PowershellProjectVersion -ProjectFile $ProjectFile
            }
            $projectData = Import-Clixml -Path $ProjectFile

            if ( $ProjectFile.StartsWith(".\") )
            {
                $projectFileKey = $ProjectFile.SubString(2)
            }        
            if ( $projectData.ContainsKey($projectFileKey) )
            {
                $projectData.Remove($projectFileKey)
            }
            if ( $projectData.ContainsKey("ISEPSProjectDataVersion") )
            {
                $projectData.Remove("ISEPSProjectDataVersion")
            }

            $activeTabs = $psISE.PowerShellTabs

            $removeTabs = @()
            foreach ( $tab in $activeTabs )
            {
                $activeFiles = $tab.Files
                $removeFiles = @()
                foreach ( $file in $activeFiles )
                {
                    Write-Verbose "Checking: $($file.DisplayName)"
                    if ( $projectData.ContainsKey($file.DisplayName) ) 
                    {
                        Write-Verbose "Found Key, it lives on $($projectData[$file.Displayname])"
                        if ( ($projectData[$file.DisplayName]).ProjectTab -eq $tab.DisplayName ) 
                        {
                            Write-Verbose "Key is in current tab"
                            #this file on this tab IS part of the project and can be closed, if it hasn't been saved.
                            if ( $file.IsSaved ) 
                            {
                                $removeFiles += $file
                            }
                        }
                    }
                }
                foreach ( $file in $removeFiles )
                {
                    Write-Verbose "Attempting to close: $($file.DisplayName)"
                    $tab.Files.Remove($file)            
                }
                if ( $tab.Files.Count -eq 0 ) 
                {
                    $removeTabs += $tab
                }
            }

            foreach ( $tab in $removeTabs ) 
            {
                Write-Verbose "Removing Empty Tab: $($tab.DisplayName)"
                $psise.PowerShellTabs.Remove($tab)
            }
        } #continue processing
   }
    End
    {
        if ( $continueProcessing -eq $true )
        {

        }
    }
}
<#
.Synopsis
   Removes abandoned files from the .psproj file.
.DESCRIPTION
   Occasionally you will have removed/renamed source files and since we are doing ValidateScripts on passed in source file names these cannot be removed using the Remove-SourceFromPowerShellProject cmdlet.
 
   This command will loop through the .psproj file's source files and determine if they exist, and if not, they will be removed.
.EXAMPLE
PS> Get-ChildItem
 
 
    Directory: C:\Powershell\ISEPSProject
 
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/28/2016 10:12 AM 11291 Add-SourceToPowershellProject.ps1
-a---- 12/28/2016 10:26 AM 2470 Clean-PowershellProject.ps1
-a---- 12/27/2016 7:46 PM 1715 Compare-PowershellProjectBackup.ps1
-a---- 12/28/2016 8:06 AM 5637 Create-PowershellProject.ps1
-a---- 12/28/2016 10:22 AM 1688 Get-PowershellProject.ps1
-a---- 12/27/2016 7:45 PM 916 Get-PowershellProjectBackup.ps1
-a---- 12/28/2016 10:14 AM 2648 ISEPSProject.psproj
-a---- 12/28/2016 7:23 AM 2035 Open-PowershellProject.ps1
-a---- 12/28/2016 10:12 AM 5237 Remove-SourceFromPowershellProject.ps1
 
 
 
PS> New-Item -Path DoNothing-OnNothing.ps1 -ItemType File
 
 
    Directory: C:\Powershell\ISEPSProject
 
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/28/2016 10:27 AM 0 DoNothing-OnNothing.ps1
 
 
 
PS> Add-SourceToPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile .\DoNothing-OnNothing.ps1 -ProjectTab "ISE PSProj"
1 file(s) have been added to the project
0 duplicate file(s) have been skipped
 
PS> Get-PowershellProject -ProjectFile .\ISEPSProject.psproj
 
Name Value
---- -----
Add-SourceToPowershellProject.ps1 ISE PSProj
Remove-SourceFromPowershellProject.ps1 ISE PSProj
Create-PowershellProject.ps1 ISE PSProj
Open-PowershellProject.ps1 ISE PSProj
Clean-PowershellProject.ps1 ISE PSProj
Get-PowershellProjectBackup.ps1 ISE PSProj
Compare-PowershellProjectBackup.ps1 ISE PSProj
DoNothing-OnNothing.ps1 ISE PSProj
Get-PowershellProject.ps1 ISE PSProj
 
PS> Remove-Item -Path .\DoNothing-OnNothing.ps1
 
PS> Get-ChildItem
 
 
    Directory: C:\Powershell\ISEPSProject
 
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/28/2016 10:12 AM 11291 Add-SourceToPowershellProject.ps1
-a---- 12/28/2016 10:26 AM 2470 Clean-PowershellProject.ps1
-a---- 12/27/2016 7:46 PM 1715 Compare-PowershellProjectBackup.ps1
-a---- 12/28/2016 8:06 AM 5637 Create-PowershellProject.ps1
-a---- 12/28/2016 10:22 AM 1688 Get-PowershellProject.ps1
-a---- 12/27/2016 7:45 PM 916 Get-PowershellProjectBackup.ps1
-a---- 12/28/2016 10:28 AM 2868 ISEPSProject.psproj
-a---- 12/28/2016 7:23 AM 2035 Open-PowershellProject.ps1
-a---- 12/28/2016 10:12 AM 5237 Remove-SourceFromPowershellProject.ps1
 
 
 
PS> Remove-SourceFromPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile DoNothing-OnNothing.ps1
Remove-SourceFromPowershellProject : Cannot validate argument on parameter 'SourceFile'. The " Test-Path $_ " validation script for the argument with value "DoNothing-OnNothing.ps1" did not return a result of
True. Determine why the validation script failed, and then try the command again.
At line:1 char:83
+ ... ProjectFile .\ISEPSProject.psproj -SourceFile DoNothing-OnNothing.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [Remove-SourceFromPowershellProject], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Remove-SourceFromPowershellProject
  
 
PS> Clean-PowershellProject -ProjectFile .\ISEPSProject.psproj
1 source file(s) have been removed from the project.
#>

function Clean-PowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]       
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
    )

    Begin
    {
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true )
        {
            $projectData = Import-Clixml -Path $ProjectFile

            $removedItems = 0
            $removeKey = @()
            foreach ( $key in $projectData.Keys )
            {
                Write-Verbose "Checking $key"
                if ( -Not ( Test-Path $key ) ) 
                {
                    $removeKey += $key
                    $removedItems++
                }
            }

            foreach ( $item_removeKey in $removeKey ) 
            {
                $projectData.Remove($item_removeKey)
            }

            Save-PowershellProject -ProjectFile $ProjectFile -ProjectData $projectData

            Write-Output "$($removedItems) source file(s) have been removed from the project."
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true )
        {

        }
    }
}
<#
.Synopsis
    Set the IncludeInBuild flag for a source file.
.DESCRIPTION
    Each source item in the .psproj file contains a flag named IncludeInBuild. This flag drives the inclusion of the source file in the Build-PowershellProject command.
.EXAMPLE
PS> (Get-PowershellProject)["Open-PowershellProject.ps1"]
 
FileName ProjectTab IncludeInBuild
-------- ---------- --------------
Open-PowershellProject.ps1 ISE PSProj True
 
PS> Set-IncludeInBuildFlagForSource -ProjectFile .\ISEPSProject.psproj -SourceFile Open-PowershellProject.ps1 -Exclude
1 source file(s) have been updated in the project
0 source file(s) were not found in the project
 
PS> (Get-PowershellProject)["Open-PowershellProject.ps1"]
 
FileName ProjectTab IncludeInBuild
-------- ---------- --------------
Open-PowershellProject.ps1 ISE PSProj False
 
.EXAMPLE
PS> Set-IncludeInBuildFlagForSource -ProjectFile .\ISEPSProject.psproj -SourceFile Open-PowershellProject.ps1 -Include
1 source file(s) have been updated in the project
0 source file(s) were not found in the project
 
PS> (Get-PowershellProject)["Open-PowershellProject.ps1"]
 
FileName ProjectTab IncludeInBuild
-------- ---------- --------------
Open-PowershellProject.ps1 ISE PSProj True
 
.EXAMPLE
PS> $projectData = Get-PowershellProject -ProjectFile .\ISEPSProject.psproj
PS> Set-IncludeInBuildFlagForSource -ProjectFile .\ISEPSProject.psproj -SourceFile $projectData.Keys -Exclude
13 source file(s) have been updated in the project
0 source file(s) were not found in the project
 
PS> (Get-PowershellProject).Values | Format-Table -AutoSize
 
FileName ProjectTab IncludeInBuild
-------- ---------- --------------
Remove-SourceFromPowershellProject.ps1 ISE PSProj False
Build-PowershellProject.ps1 ISE PSProj False
Close-PowershellProject.ps1 ISE PSProj False
Clean-PowershellProject.ps1 ISE PSProj False
Set-IncludeInBuildFlagForSource.ps1 ISE PSProj False
Open-PowershellProject.ps1 ISE PSProj False
Get-PowershellProjectBackup.ps1 ISE PSProj Backup False
UtilityFunctions.ps1 ISE PSProj False
Compare-PowershellProjectBackup.ps1 ISE PSProj Backup False
Set-PowershellProjectDefaults.ps1 ISE PSProj False
Get-PowershellProject.ps1 ISE PSProj False
Add-SourceToPowershellProject.ps1 ISE PSProj False
Create-PowershellProject.ps1 ISE PSProj False
 
.EXAMPLE
PS> $projectData = Get-PowershellProject -ProjectFile .\ISEPSProject.psproj
PS> $singleTab = $projectData.GetEnumerator() | Where-Object { $_.Value.ProjectTab -eq "ISE PSProj" }
PS> Set-IncludeInBuildFlagForSource -ProjectFile .\ISEPSProject.psproj -SourceFile $singleTab.Key -Include
11 source file(s) have been updated in the project
0 source file(s) were not found in the project
 
PS> (Get-PowershellProject).Values | Format-Table -AutoSize
 
FileName ProjectTab IncludeInBuild
-------- ---------- --------------
Remove-SourceFromPowershellProject.ps1 ISE PSProj True
Build-PowershellProject.ps1 ISE PSProj True
Close-PowershellProject.ps1 ISE PSProj True
Clean-PowershellProject.ps1 ISE PSProj True
Set-IncludeInBuildFlagForSource.ps1 ISE PSProj True
Open-PowershellProject.ps1 ISE PSProj True
Get-PowershellProjectBackup.ps1 ISE PSProj Backup False
UtilityFunctions.ps1 ISE PSProj True
Compare-PowershellProjectBackup.ps1 ISE PSProj Backup False
Set-PowershellProjectDefaults.ps1 ISE PSProj True
Get-PowershellProject.ps1 ISE PSProj True
Add-SourceToPowershellProject.ps1 ISE PSProj True
Create-PowershellProject.ps1 ISE PSProj True
 
#>

function Set-IncludeInBuildFlagForSource
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]       
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
        ,
        # Specify the source file to set the IncludeInBuild flag for.
        [Parameter(Mandatory=$true,
                   Position=1)]
        [Alias('Source','SourcePath')]
        [ValidateScript({ Test-Path $_ })]
        [string[]]
        $SourceFile
        ,
        # Use this switch to EXCLUDE the source file from the build process, -Include overrides -Exclude.
        [Parameter(Mandatory=$false,
                   Position=2)]
        [switch]
        $Exclude
        ,
        # Use this switch to INCLUDE the source file in the build process, -Include overrides -Exclude.
        # -Include is the default operation.
        [Parameter(Mandatory=$false,
                   Position=3)]
        [switch]
        $Include
    )

    Begin
    {           
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
        if ( ( $Exclude -eq $true ) -and ( $Include -eq $true ) )
        {
            $Exclude = $false            
        }   
        if ( ( $Exclude -eq $false ) -and ( $Include -eq $false ) ) 
        {
            $Include = $true
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true )
        {
            if ( (Get-PowershellProjectVersion -ProjectFile $ProjectFile).IsLatest -eq $false )
            {
                Update-PowershellProjectVersion -ProjectFile $ProjectFile
            }
            $projectData = Import-Clixml -Path $ProjectFile

            $updatedItems = 0
            $notFoundItems = 0  
            $keyToUpdate = @()      
            foreach ($item_SourceFile in $SourceFile)
            {
                if ( $item_SourceFile.StartsWith(".\") )
                {
                    $item_SourceFile = $item_SourceFile.SubString(2)
                }        
           
                if ( $projectData.ContainsKey($item_SourceFile) )
                {
                    $keyToUpdate += $item_SourceFile
                } else {
                    $notFoundItems++
                }
            }
            foreach ( $item_keyToUpdate in $keyToUpdate )
            {
                $item = $projectData[$item_keyToUpdate]
                if ( $Include -eq $true ) 
                {
                    $item.IncludeInBuild = $true
                }
                if ( $Exclude -eq $true ) 
                {
                    $item.IncludeInBuild = $false
                }
                $projectData[$item_keyToUpdate] = $item
                $updatedItems++
            }

            Save-PowershellProject -ProjectFile $ProjectFile -ProjectData $projectData
        
            Write-Output "$($updatedItems) source file(s) have been updated in the project"
            Write-Output "$($notFoundItems) source file(s) were not found in the project"
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true ) 
        {
        }
    }
}
<#
.Synopsis
   Open a Powershell .PSPROJ file in ISE, separated by TABS
.DESCRIPTION
   Define a collection of scripts and open them in a single command.
 
   This process will loop through the Source files and their associated Project TAB names and open new TABs and open the Source files on those TABs.
 
 
.EXAMPLE
   Open-PowershellProject -ProjectFile ISEPSProject.psproj
#>

function Open-PowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
    )

    Begin
    {   
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true ) 
        {

            if ( (Get-PowershellProjectVersion -ProjectFile $ProjectFile).IsLatest -eq $false )
            {
                Update-PowershellProjectVersion -ProjectFile $ProjectFile
            }
            $projectData = Import-Clixml -Path $ProjectFile

            if ( $ProjectFile.StartsWith(".\") )
            {
                $projectFileKey = $ProjectFile.SubString(2)
            }        
            if ( $projectData.ContainsKey($projectFileKey) )
            {
                $projectData.Remove($projectFileKey)
            }
            if ( $projectData.ContainsKey("ISEPSProjectDataVersion") )
            {
                $projectData.Remove("ISEPSProjectDataVersion")
            }

            $tab = ($projectData.Values | Select-Object -Property ProjectTab | Sort-Object -Property ProjectTab -Unique).ProjectTab
            foreach ( $item_tab in $tab ) 
            {
                $newTab = $psISE.PowerShellTabs.Add()
                $newTab.DisplayName = $item_tab            

                $sourceFile = $projectData.GetEnumerator() | Where-Object { $_.Value.ProjectTab -eq $item_tab }
                foreach ( $item_sourceFile in $sourceFile ) 
                {
                    Write-Verbose "Opening: $(Get-Location)\$($item_sourceFile.Name)"
                    $newTab.Files.Add("$(Get-Location)\$($item_sourceFile.Name)")
                }
                $pwd = Get-Location
                Start-Sleep -Seconds 1
                $newTab.Invoke("Set-Location $pwd")
            }
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true ) 
        {
        }
    }
}
<#
.Synopsis
   Returns the most current version of .psproj files.
.DESCRIPTION
   Returns the lastest version of the .psproj files supported by the code.
 
.EXAMPLE
   Get-PowershellProjectCurrentVersion
#>

function Get-PowershellProjectCurrentVersion
{
    [CmdletBinding()]
    Param
    (        
    )

    Begin
    {        
    }
    Process
    {        
        $item = "" | Select-Object CurrentVersion
        $item.CurrentVersion = "1.1"
        Write-Output $item
   }
    End
    {
    }
}

<#
.Synopsis
   Get the .psproj data version
.DESCRIPTION
   Returns the version of the .psproj data
 
.EXAMPLE
PS> Get-PowershellProjectVersion -ProjectFile ISEPSProject.psproj
 
Version CurrentVersion IsLatest
------- -------------- --------
1.1 1.1 True
 
#>

function Get-PowershellProjectVersion
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
    )

    Begin
    {
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true )
        {
            $projectData = Import-Clixml -Path $ProjectFile
            $item = "" | Select-Object Version,CurrentVersion,IsLatest
            $item.CurrentVersion = (Get-PowershellProjectCurrentVersion).CurrentVersion
            $item.IsLatest = $false
        
            if ( $projectData.ContainsKey("ISEPSProjectDataVersion") )
            {
                $item.Version = $projectData["ISEPSProjectDataVersion"]
            } else {
                $item.Version = "1.0"
            }
            if ( $item.CurrentVersion -eq $item.Version ) 
            {
                $item.IsLatest = $true
            }
            Write-Output $item
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true )
        {
        }
    }
}
<#
.Synopsis
   Process to upgrade from a previous version to current.
.DESCRIPTION
   When the existing .psproj file is not at the current version, calling this command will upgrade all previous version to the current version.
 
.EXAMPLE
PS> Update-PowershellProjectVersion -ProjectFile ISEPSProject.psproj
 
UpgradeNeeded UpgradeStatus
------------- -------------
         True Updated to latest
 
#>

function Update-PowershellProjectVersion
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
    )

    Begin
    {    
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true )
        {
            $projectData = Import-Clixml -Path $ProjectFile

            $dataVersion = Get-PowershellProjectVersion -ProjectFile $ProjectFile
            $item = "" | Select-Object UpgradeNeeded,UpgradeStatus

            if ( $dataVersion.Version -ne $dataVersion.CurrentVersion ) 
            {
                Write-Verbose "Need an update: $($dataVersion.Version) to $($dataVersion.CurrentVersion)"
                $bakProjectData = Get-Content -Path $ProjectFile

                $backupList =  Get-Item -Path $ProjectFile -Stream * | Where-Object { $_.Stream -ne ':$DATA' }  | Sort-Object -Property Stream -Descending
                if ( $backupList )
                {
                    if ( $backupList.Count -gt 8 ) { $backupCount = 8 } else { $backupCount = ($backupList.Count)-1 }
                    $backupData = @{}
                    for ( $x = 0; $x -le $backupCount; $x++ )
                    {
                        $backData = Get-Content -Path $ProjectFile -Stream $backupList[$x].Stream
                        $backupData.Add($backupList[$x].Stream, $backData)
                    }
                }


                if ( ( $dataVersion.Version -eq "1.1" ) -and ( $continueProcessing -eq $true ) )
                {
                    #current version
                    $item.UpgradeNeeded = $false
                    $item.UpgradeStatus = "Current"
                    $continueProcessing = $false
                }
                if ( ( $dataVersion.Version -eq "1.0" ) -and ( $continueProcessing -eq $true ) )
                {
                    #upgrade from 1.0
                    Write-Verbose "Update from 1.0"
                    $projectData.Add("ISEPSProjectDataVersion", "1.1")

                    if ( $ProjectFile.StartsWith(".\") )
                    {
                        $projectFileKey = $ProjectFile.SubString(2)
                    }    
                    $newProjectData = @{}    
                    foreach ( $key in $projectData.Keys )
                    {
                        if ( ( $key -ne $projectFileKey ) -and ( $key -ne "ISEPSProjectDataVersion" ) ) 
                        {
                            $newStruct = "" | Select-Object FileName,ProjectTab,IncludeInBuild
                            $newStruct.FileName = $key
                            $newStruct.ProjectTab = $projectData[$key]
                            $newStruct.IncludeInBuild = $true
                            $newProjectData.Add($key, $newStruct)
                        } else {
                            $newProjectData.Add($key, $projectData[$key])
                        }
                    }
                    $item.UpgradeNeeded = $true
                    $item.UpgradeStatus = "Updated to latest"
                    $continueProcessing = $true
                }

                if ( $continueProcessing -eq $true ) 
                {
                    $newProjectData | Export-Clixml -Path $ProjectFile -Force

                    $backupName = (Get-Date).ToString('yyyy-MM-dd_HHmmss')
                    Add-Content -Path $ProjectFile -Value $bakProjectData -Stream $backupName

                    foreach ( $key in $backupData.Keys )
                    {
                        Add-Content -Path $ProjectFile -Value $backupData.Get_Item($key) -Stream $key
                    }                
                }
            } else {
                $item.UpgradeNeeded = $false
                $item.UpgradeStatus = "Current"
            }
            Write-Output $item
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true )
        {
        }
    }
}
<#
.Synopsis
   Gets the BACKUP Data from a .psproj file.
.DESCRIPTION
   Returns a hash table of backup data.
 
.EXAMPLE
PS> $backupData = Get-PowershellProjectBackupData -ProjectFile ISEPSProject.psproj
PS> $backupData
Name Value
---- -----
2017-08-29_112937 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
2017-08-29_112834 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
2017-08-29_113448 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
2017-08-28_141817 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
2017-08-29_113355 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
2017-08-29_112646 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
2017-08-29_080326 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
2017-08-28_141113 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
2017-08-28_144227 {<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">, <Obj ...
 
#>

function Get-PowershellProjectBackupData
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
        ,
        # Switch to return ALL backups, instead of the previous 9.
        [Parameter(Mandatory=$false,
                   Position=1)]
        [switch]
        $AllBackups
    )

    Begin
    {
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true )
        {
            $bakProjectData = Get-Content -Path $ProjectFile

            $backupList =  Get-Item -Path $ProjectFile -Stream * | Where-Object { $_.Stream -ne ':$DATA' }  | Sort-Object -Property Stream -Descending
            if ( $backupList )
            {
                if ( $backupList.Count -gt 8 ) 
                {
                    if ( $AllBackups -eq $true )
                    {
                        $backupCount = ($backupList.Count)-1
                    } else {
                        $backupCount = 8 
                    }
                } else {
                    $backupCount = ($backupList.Count)-1 
                }
                $backupData = @{}
                for ( $x = 0; $x -le $backupCount; $x++ )
                {
                    $backData = Get-Content -Path $ProjectFile -Stream $backupList[$x].Stream
                    $backupData.Add($backupList[$x].Stream, $backData)
                }
            }
            Write-Output $backupData
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true )
        {
        }
    }
}
<#
.Synopsis
   Save a .psproj file.
.DESCRIPTION
   This process saves, and optionally stores backups within the NTFS streams of the file.
 
.EXAMPLE
PS> $projectData = Get-PowershellProject -ProjectFile ISEPSProject.psproj
PS> Save-PowershellProject -ProjectFile ISEPSProject.psproj -ProjectData $projectData
 
#>

function Save-PowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
        ,
        #backup data gathered from the Get-PowershellProjectBackupData command.
        [Parameter(Mandatory=$false,
                   Position=1)]
        [Hashtable]
        $ProjectData
        ,
        #Skip backing up the current file data, just write the $ProjectData values.
        [Parameter(Mandatory=$false,
                   Position=2)]
        [switch]
        $SkipBackup = $false
    )

    Begin
    {
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true )
        {
            if ( $SkipBackup -eq $false )
            {
                $bakProjectData = Get-Content -Path $ProjectFile
                $backupData = Get-PowershellProjectBackupData $ProjectFile
            } else {
                $backupData = Get-PowershellProjectBackupData $ProjectFile -AllBackups
            }

            $projectData | Export-Clixml -Path $ProjectFile -Force

            if ( $SkipBackup -eq $false )
            {
                $backupName = (Get-Date).ToString('yyyy-MM-dd_HHmmss')
                Add-Content -Path $ProjectFile -Value $bakProjectData -Stream $backupName

                foreach ( $key in $backupData.Keys )
                {
                    Add-Content -Path $ProjectFile -Value $backupData.Get_Item($key) -Stream $key
                }
            } else {
                foreach ( $key in $backupData.Keys )
                {
                    Add-Content -Path $ProjectFile -Value $backupData.Get_Item($key) -Stream $key
                }
            }
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true )
        {
        }
    }
}
<#
.Synopsis
   Save a .psproj\defaults.clixml file. This will allow you to skip the -ProjectFile parameter and sets the default IncludeInBuild option for adding items to the project.
.DESCRIPTION
   This is simply a file that will be read by each of the commands in order to pre-populate the -ProjectFile and -IncludeInBuild parameters.
 
.EXAMPLE
PS> $default = "" | Select-Object ProjectFile,IncludeInBuild
PS> $defualt.ProjectFile = ".\ISEPSProject.psproj"
PS> $default.IncludeInBuild = $true
PS> Save-PowershellProjectDefaults -DefaultData $default
#>

function Save-PowershellProjectDefaults
{
    [CmdletBinding()]
    Param
    (
        # Default data in the form of $default = "" | Select-Object ProjectFile,IncludeInBuild
        [Parameter(Mandatory=$true,
                   Position=0)]
        [PSObject]
        $DefaultData
    )

    Begin
    {        
    }
    Process
    {
        $DefaultData | Export-Clixml -Path ".\.psproj\defaults.clixml" -Force
    }
    End
    {
    }
}
<#
.Synopsis
   Extract the ProjectFile default from .psproj\defaults.clixml file.
.DESCRIPTION
   Called by the commands to fetch the default value for ProjectFile.
 
.EXAMPLE
For Use in [Parameters]
   $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
#>

function Get-PowershellProjectDefaultProjectFile
{
    [CmdletBinding()]
    Param
    (       
    )

    Begin
    {        
    }
    Process
    {
        if ( Test-Path ".\.psproj\defaults.clixml" ) 
        {
            $defaults = Import-Clixml -Path ".\.psproj\defaults.clixml"
            if ( Test-Path $defaults.ProjectFile ) 
            {
                Write-Output $defaults.ProjectFile
            } else {
                Write-Output ""
            }
        } else {
            Write-Output ""
        }
    }
    End
    {
    }
}
<#
.Synopsis
   Gets a list of the commands (function) inside of the source files contained in the .psproj file.
.DESCRIPTION
   Generate a list of commands (function) with their containing source file information.
 
.EXAMPLE
PS> Get-PowershellProjectFunctions -ProjectFile .\ISEPSProject.psproj | Sort-Object -Property SourceFile,FunctionName
 
FunctionName SourceFile
------------ ----------
Add-SourceToPowershellProject Add-SourceToPowershellProject.ps1
Build-PowershellProject Build-PowershellProject.ps1
Clean-PowershellProject Clean-PowershellProject.ps1
Close-PowershellProject Close-PowershellProject.ps1
Compare-PowershellProjectBackup Compare-PowershellProjectBackup.ps1
Create-PowershellProject Create-PowershellProject.ps1
Get-PowershellProject Get-PowershellProject.ps1
Get-PowershellProjectBackup Get-PowershellProjectBackup.ps1
Open-PowershellProject Open-PowershellProject.ps1
Remove-SourceFromPowershellProject Remove-SourceFromPowershellProject.ps1
Set-IncludeInBuildFlagForSource Set-IncludeInBuildFlagForSource.ps1
Set-PowershellProjectDefaults Set-PowershellProjectDefaults.ps1
Get-CSVFromStringArray UtilityFunctions.ps1
Get-PowershellProjectBackupData UtilityFunctions.ps1
Get-PowershellProjectCurrentVersion UtilityFunctions.ps1
Get-PowershellProjectDefaultIncludeInBuild UtilityFunctions.ps1
Get-PowershellProjectDefaultProjectFile UtilityFunctions.ps1
Get-PowershellProjectFunctions UtilityFunctions.ps1
Get-PowershellProjectVersion UtilityFunctions.ps1
Save-PowershellProject UtilityFunctions.ps1
Save-PowershellProjectDefaults UtilityFunctions.ps1
Update-PowershellProjectVersion UtilityFunctions.ps1
 
.EXAMPLE
PS> Get-PowershellProjectFunctions -ProjectFile .\ISEPSProject.psproj -IncludedInBuildOnly | Sort-Object -Property SourceFile,FunctionName
 
FunctionName SourceFile
------------ ----------
Add-SourceToPowershellProject Add-SourceToPowershellProject.ps1
Build-PowershellProject Build-PowershellProject.ps1
Clean-PowershellProject Clean-PowershellProject.ps1
Close-PowershellProject Close-PowershellProject.ps1
Create-PowershellProject Create-PowershellProject.ps1
Get-PowershellProject Get-PowershellProject.ps1
Open-PowershellProject Open-PowershellProject.ps1
Remove-SourceFromPowershellProject Remove-SourceFromPowershellProject.ps1
Set-IncludeInBuildFlagForSource Set-IncludeInBuildFlagForSource.ps1
Set-PowershellProjectDefaults Set-PowershellProjectDefaults.ps1
Get-CSVFromStringArray UtilityFunctions.ps1
Get-PowershellProjectBackupData UtilityFunctions.ps1
Get-PowershellProjectCurrentVersion UtilityFunctions.ps1
Get-PowershellProjectDefaultIncludeInBuild UtilityFunctions.ps1
Get-PowershellProjectDefaultProjectFile UtilityFunctions.ps1
Get-PowershellProjectFunctions UtilityFunctions.ps1
Get-PowershellProjectVersion UtilityFunctions.ps1
Save-PowershellProject UtilityFunctions.ps1
Save-PowershellProjectDefaults UtilityFunctions.ps1
Update-PowershellProjectVersion UtilityFunctions.ps1
 
#>

function Get-PowershellProjectFunctions
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
        ,
        # Switch to only include those source files that have the IncludeInBuild flag set.
        [Parameter(Mandatory=$false,
                   Position=1)]
        [switch]
        $IncludedInBuildOnly = $false
    )

    Begin
    {
        $functionList = @()
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true ) 
        {
            $projectData = Import-Clixml -Path $ProjectFile
            if ( $ProjectFile.StartsWith(".\") )
            {
                $projectFileKey = $ProjectFile.SubString(2)
            }        
            if ( $projectData.ContainsKey($projectFileKey) )
            {
                $projectData.Remove($projectFileKey)
            }
            if ( $projectData.ContainsKey("ISEPSProjectDataVersion") )
            {
                $projectData.Remove("ISEPSProjectDataVersion")
            }

            if ( $IncludedInBuildOnly -eq $true ) 
            {
                $includedSources = ($projectData.Values | Where-Object { $_.IncludeInBuild -eq $true } | Select-Object -Property FileName | Sort-Object -Property FileName).FileName
            } else {
                $includedSources = ($projectData.Values | Select-Object -Property FileName | Sort-Object -Property FileName).FileName
            }

            foreach ( $key in $includedSources )
            {
                $content = Get-Content -Path $key
                foreach ( $line in $content )
                {
                    if ( $line.Trim().StartsWith("function") )
                    {
                        $item = "" | Select-Object FunctionName,SourceFile
                        $item.FunctionName = $line.Trim().Split(" ")[1]
                        $item.SourceFile = $key
                        $functionList += $item
                    }
                }
            }
            Write-Output $functionList
        } #continue processing
   }
    End
    {
        if ( $continueProcessing -eq $true )
        {
        }
    }
}
<#
.Synopsis
   Extract the IncludeInBuild default from .psproj\defaults.clixml file.
.DESCRIPTION
   Called by the commands to fetch the default value for IncludeInBuild.
 
.EXAMPLE
For Use in [Parameters]
   $IncludeInBuild = (Get-PowershellProjectDefaultIncludeInBuild)
#>

function Get-PowershellProjectDefaultIncludeInBuild
{
    [CmdletBinding()]
    Param
    (    
    )

    Begin
    {        
    }
    Process
    {
        if ( Test-Path ".\.psproj\defaults.clixml" ) 
        {
            $defaults = Import-Clixml -Path ".\.psproj\defaults.clixml"
            Write-Output $defaults.IncludeInBuild
        } else {
            Write-Output $false
        }
    }
    End
    {
    }
}
<#
.Synopsis
   Given a [string[]] array, convert it to a CSV formatted string.
.DESCRIPTION
   Used by the Build-PowershellProject command to output the FunctionsToExport = line for inclusion in the psd1 file.
 
.EXAMPLE
PS> $functionInfo = (Get-PowershellProjectFunctions -ProjectFile .\ISEPSProject.psproj -IncludedInBuildOnly | Sort-Object -Property SourceFile,FunctionName).FunctionName
PS> Get-CSVFromStringArray -StringArray $functionInfo -SingleQuotes
'Add-SourceToPowershellProject','Build-PowershellProject','Clean-PowershellProject','Close-PowershellProject','Create-PowershellProject','Get-PowershellProject','Open-PowershellP
roject','Remove-SourceFromPowershellProject','Set-IncludeInBuildFlagForSource','Set-PowershellProjectDefaults','Get-CSVFromStringArray','Get-PowershellProjectBackupData','Get-Pow
ershellProjectCurrentVersion','Get-PowershellProjectDefaultIncludeInBuild','Get-PowershellProjectDefaultProjectFile','Get-PowershellProjectFunctions','Get-PowershellProjectVersio
n','Save-PowershellProject','Save-PowershellProjectDefaults','Update-PowershellProjectVersion'
#>

function Get-CSVFromStringArray
{
    [CmdletBinding()]
    Param
    (
        # String Array to convert to CSV Line
        [Parameter(Mandatory=$false,
                   Position=0)]
        [string[]]
        $StringArray
        ,
        # Add single quotes around each element
        [Parameter(Mandatory=$false,
                   Position=1)]
        [switch]
        $SingleQuotes
    )

    Begin
    {   
        $csvLine = ""
    }
    Process
    {
        foreach ( $string in $StringArray )
        {
            if ( $SingleQuotes -eq $true )
            {
                $csvLine += "'$($string)',"
            } else {
                $csvLine += "$($string),"
            }
        }
    }
    End
    {
        $csvLine = $csvLine.Substring(0, $csvLine.Length-1)        
        Write-Output $csvLine
    }
}
<#
.Synopsis
   Set some default values for common parameters (-ProjectFile and -IncludeInBuild)
.DESCRIPTION
   To avoid having to constantly call out the -ProjectFile and -IncludeInBuild parameters we will store some default values in .\.psproj\defaults.clixml file.
   All commands that have these parameters will attempt to read the defaults.clixml data if the parameter is excluded from the command.
.EXAMPLE
PS> Set-PowershellProjectDefaults -ProjectFile .\ISEPSProject.psproj
 
PS> Set-PowershellProjectDefaults -IncludeInBuild No
 
PS> Get-PowershellProjectDefaultProjectFile
.\ISEPSProject.psproj
 
PS> Get-PowershellProjectDefaultIncludeInBuild
False
 
#>

function Set-PowershellProjectDefaults
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to save as the default.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        [ValidateScript({ Test-Path $_ })]
        [string]
        $ProjectFile
        ,
        # Specify Yes/No to set the default IncludeInBuild to be used when running the Add-SourceToPowershellProject command.
        [Parameter(Mandatory=$false,
                   Position=1)]
        [ValidateSet("Don't Modify","Yes","No")]
        [string]
        $IncludeInBuild = "Don't Modify"
    )

    Begin
    {
        $continueProcessing = $true
    }
    Process
    {
        if ( $continueProcessing -eq $true ) 
        {
            if ( -not ( Test-Path ".\.psproj" ) )
            {
                New-Item -Path ".\.psproj" -ItemType Directory
                #create new
                $defaults = "" | Select-Object ProjectFile,IncludeInBuild
                if ( ( $ProjectFile -ne "" ) -and ( Test-Path $ProjectFile ) ) 
                {
                    $defaults.ProjectFile = $ProjectFile
                }
                if ( $IncludeInBuild -eq "Yes" )
                {
                    $defaults.IncludeInBuild = $true 
                } else {
                    $defaults.IncludeInBuild = $false
                }                   
            } else {
                if ( Test-Path ".\.psproj\defaults.clixml" )
                {
                    #read and update
                    $defaults = Import-Clixml -Path ".\.psproj\defaults.clixml"
                    if ( ( $ProjectFile -ne "" ) -and ( Test-Path $ProjectFile ) ) 
                    {
                        $defaults.ProjectFile = $ProjectFile
                    }
                    if ( $IncludeInBuild -ne "Don't Modify" ) 
                    {
                        if ( $IncludeInBuild -eq "Yes" )
                        {
                            $defaults.IncludeInBuild = $true 
                        } else {
                            $defaults.IncludeInBuild = $false
                        }
                    }
                    
                } else {
                    #create new
                    $defaults = "" | Select-Object ProjectFile,IncludeInBuild
                    if ( ( $ProjectFile -ne "" ) -and ( Test-Path $ProjectFile ) ) 
                    {
                        $defaults.ProjectFile = $ProjectFile
                    }
                    if ( $IncludeInBuild -eq "Yes" )
                    {
                        $defaults.IncludeInBuild = $true 
                    } else {
                        $defaults.IncludeInBuild = $false
                    }
                }
            }
            Save-PowershellProjectDefaults -DefaultData $defaults
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true ) 
        {
        }
    }
}

<#
.Synopsis
   Display a list of source files contained in the .psproj file.
.DESCRIPTION
   Used to view the list of files and their associated data.
 
   Sources files are in the NAME column, and the associated item details are in the Value column.
 
   Value column structure:
   Filename: matches the Name field.
   ProjectTab: name of the ISE TAB the file will be opened on.
   IncludeInBuild: True/False value for including the source file in the building of the psm1 file.
.EXAMPLE
PS> Get-PowershellProject -ProjectFile .\ISEPSProject.psproj | Format-Table -AutoSize
 
Name Value
---- -----
Remove-SourceFromPowershellProject.ps1 @{FileName=Remove-SourceFromPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Build-PowershellProject.ps1 @{FileName=Build-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Close-PowershellProject.ps1 @{FileName=Close-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Clean-PowershellProject.ps1 @{FileName=Clean-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Set-IncludeInBuildFlagForSource.ps1 @{FileName=Set-IncludeInBuildFlagForSource.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Open-PowershellProject.ps1 @{FileName=Open-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Get-PowershellProjectBackup.ps1 @{FileName=Get-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj Backup; IncludeInBuild=False}
Get-PowershellProject.ps1 @{FileName=Get-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Compare-PowershellProjectBackup.ps1 @{FileName=Compare-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj Backup; IncludeInBuild=False}
Set-PowershellProjectDefaults.ps1 @{FileName=Set-PowershellProjectDefaults.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
UtilityFunctions.ps1 @{FileName=UtilityFunctions.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Add-SourceToPowershellProject.ps1 @{FileName=Add-SourceToPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Create-PowershellProject.ps1 @{FileName=Create-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
#>

function Get-PowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]       
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
    )

    Begin
    {    
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true ) 
        {
            $projectData = Import-Clixml -Path $ProjectFile

            if ( $ProjectFile.StartsWith(".\") )
            {
                $projectFileKey = $ProjectFile.SubString(2)
            } else {
                $projectFileKey = $ProjectFile
            }
            if ( $projectData.ContainsKey($projectFileKey) )
            {
                $projectData.Remove($projectFileKey)
            }
            if ( $projectData.ContainsKey("ISEPSProjectDataVersion") )
            {
                $projectData.Remove("ISEPSProjectDataVersion")
            }

            Write-Output $projectData
        } #continue processing
    }
    End
    {
    }
}
<#
.Synopsis
   Add a source file to an existing .psproj file.
.DESCRIPTION
   Add a source file and corresponding TAB name to the .psproj file so it can be opened as a single project later. A backup in the -streams section of the file will also be created.
   10 backups will be kept and can be listed with Get-PowershellProjectBackup function.
.EXAMPLE
PS> Get-ChildItem
 
 
    Directory: C:\Powershell\ISEPSProject
 
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/28/2016 8:10 AM 2115 Add-SourceToPowershellProject.ps1
-a---- 12/27/2016 8:04 PM 1865 Clean-PowershellProject.ps1
-a---- 12/27/2016 7:46 PM 1715 Compare-PowershellProjectBackup.ps1
-a---- 12/28/2016 8:06 AM 5637 Create-PowershellProject.ps1
-a---- 12/28/2016 7:17 AM 691 Get-PowershellProject.ps1
-a---- 12/27/2016 7:45 PM 916 Get-PowershellProjectBackup.ps1
-a---- 12/28/2016 8:06 AM 718 ISEPSProject.psproj
-a---- 12/28/2016 7:23 AM 2035 Open-PowershellProject.ps1
-a---- 12/28/2016 7:29 AM 2135 Remove-SourceFromPowershellProject.ps1
 
 
 
PS> Add-SourceToPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile .\Add-SourceToPowershellProject.ps1 -ProjectTab "ISE PSProj" -IncludeInBuild
1 file(s) have been added to the project
0 duplicate file(s) have been skipped
.EXAMPLE
PS> Get-ChildItem
 
 
    Directory: C:\Powershell\ISEPSProject
 
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/28/2016 8:10 AM 2115 Add-SourceToPowershellProject.ps1
-a---- 12/27/2016 8:04 PM 1865 Clean-PowershellProject.ps1
-a---- 12/27/2016 7:46 PM 1715 Compare-PowershellProjectBackup.ps1
-a---- 12/28/2016 8:06 AM 5637 Create-PowershellProject.ps1
-a---- 12/28/2016 7:17 AM 691 Get-PowershellProject.ps1
-a---- 12/27/2016 7:45 PM 916 Get-PowershellProjectBackup.ps1
-a---- 12/28/2016 8:06 AM 718 ISEPSProject.psproj
-a---- 12/28/2016 7:23 AM 2035 Open-PowershellProject.ps1
-a---- 12/28/2016 7:29 AM 2135 Remove-SourceFromPowershellProject.ps1
 
 
 
PS> Add-SourceToPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile .\Clean-PowershellProject.ps1,Compare-PowershellProjectBackup.ps1 -ProjectTab "ISE PSProj" -IncludeInBuild
2 file(s) have been added to the project
0 duplicate file(s) have been skipped
.EXAMPLE
PS> Get-ChildItem
 
 
    Directory: C:\Powershell\ISEPSProject
 
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/28/2016 8:26 AM 7895 Add-SourceToPowershellProject.ps1
-a---- 12/27/2016 8:04 PM 1865 Clean-PowershellProject.ps1
-a---- 12/27/2016 7:46 PM 1715 Compare-PowershellProjectBackup.ps1
-a---- 12/28/2016 8:06 AM 5637 Create-PowershellProject.ps1
-a---- 12/28/2016 8:29 AM 716 Get-PowershellProject.ps1
-a---- 12/27/2016 7:45 PM 916 Get-PowershellProjectBackup.ps1
-a---- 12/28/2016 8:28 AM 1482 ISEPSProject.psproj
-a---- 12/28/2016 7:23 AM 2035 Open-PowershellProject.ps1
-a---- 12/28/2016 7:29 AM 2135 Remove-SourceFromPowershellProject.ps1
 
 
 
PS> Get-PowershellProject -ProjectFile .\ISEPSProject.psproj
 
Name Value
---- -----
Clean-PowershellProject.ps1 @{FileName=Clean-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Compare-PowershellProjectBackup.ps1 @{FileName=Compare-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj Backup; IncludeInBuild=False}
Add-SourceToPowershellProject.ps1 @{FileName=Add-SourceToPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
      
 
PS> Add-SourceToPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile (Get-ChildItem -Filter *.ps1).Name -ProjectTab "ISE PSProj"
5 file(s) have been added to the project
3 duplicate file(s) have been skipped
.EXAMPLE
PS> Get-PowershellProject .\ISEPSProject.psproj
 
Name Value
---- -----
Remove-SourceFromPowershellProject.ps1 @{FileName=Remove-SourceFromPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Build-PowershellProject.ps1 @{FileName=Build-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Clean-PowershellProject.ps1 @{FileName=Clean-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Open-PowershellProject.ps1 @{FileName=Open-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Get-PowershellProjectBackup.ps1 @{FileName=Get-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj Backup; IncludeInBuild=False}
Get-PowershellProject.ps1 @{FileName=Get-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Compare-PowershellProjectBackup.ps1 @{FileName=Compare-PowershellProjectBackup.ps1; ProjectTab=ISE PSProj; IncludeInBuild=False}
Add-SourceToPowershellProject.ps1 @{FileName=Add-SourceToPowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
Create-PowershellProject.ps1 @{FileName=Create-PowershellProject.ps1; ProjectTab=ISE PSProj; IncludeInBuild=True}
 
 
 
PS> Add-SourceToPowershellProject -ProjectFile .\ISEPSProject.psproj -SourceFile .\Compare-PowershellProjectBackup.ps1 -ProjectTab "ISE PSProj Backup"
0 file(s) have been added to the project
0 duplicate file(s) have been skipped
1 source file(s) have had their TAB locations updated.
#>

function Add-SourceToPowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open. Default project can be specified via the Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [Alias('File','FilePath')]
        #[ValidateScript({ Test-Path $_ })]
        [string]       
        $ProjectFile = (Get-PowershellProjectDefaultProjectFile)
        ,
        # Specify the source file name to add to the project.
        [Parameter(Mandatory=$true,
                   Position=1)]
        [Alias('Source','SourcePath')]
        [ValidateScript({ Test-Path $_ })]
        [string[]]
        $SourceFile
        ,
        # Name of TAB to place the source file on when opening in ISE via the Open-PowershellProject command.
        [Parameter(Mandatory=$true,
                   Position=2)]
        [Alias('Tab','TabName')]
        [string]
        $ProjectTab
        ,
        # Flag the source file for inclusion in a module build via Build-PowershellProject command. Default can be set via Set-PowershellProjectDefaults command.
        [Parameter(Mandatory=$false,
                   Position=3)]
        [switch]
        $IncludeInBuild = (Get-PowershellProjectDefaultIncludeInBuild)
    )

    Begin
    {
        $continueProcessing = $true
        if ( $ProjectFile -ne "" ) 
        {            
            if ( -not ( Test-Path $ProjectFile ) ) 
            {
                Write-Warning "Cannot locate the specified ProjectFile"
                $continueProcessing = $false
            }        
        } else {
            Write-Warning "Must specify the -ProjectFile, or use Set-PowershellProjectDefaults command to set a default ProjectFile"
            $continueProcessing = $false
        }
    }
    Process
    {
        if ( $continueProcessing -eq $true ) 
        {
            $addCount = 0
            $duplicateCount = 0
            $updatedCount = 0

            if ( (Get-PowershellProjectVersion -ProjectFile $ProjectFile).IsLatest -eq $false )
            {
                Update-PowershellProjectVersion -ProjectFile $ProjectFile
            }
            $projectData = Import-Clixml -Path $ProjectFile        

            foreach ( $item_SourceFile in $SourceFile )
            {
                if ( $item_SourceFile.StartsWith(".\") )
                {
                    $item_SourceFile = $item_SourceFile.SubString(2)
                }        
                if ( -Not ($projectData.ContainsKey($item_Sourcefile)) )
                {
                    $item = "" | Select-Object FileName,ProjectTab,IncludeInBuild
                    $item.FileName = $item_SourceFile
                    $item.ProjectTab = $ProjectTab
                    $item.IncludeInBuild = $IncludeInBuild

                    $projectData.Add($item_SourceFile, $item)
                    $addCount++
                } else {
                    if ( ($projectData.Get_Item($item_Sourcefile)).ProjectTab -eq $ProjectTab )
                    {
                        $duplicateCount++
                    } else {
                        $item = $projectData.Get_Item($item_Sourcefile)
                        $item.ProjectTab = $ProjectTab
                        $projectData.Set_Item($item_Sourcefile, $item)
                        $updatedCount++
                    }
                }
            }

            Save-PowershellProject -ProjectFile $ProjectFile -ProjectData $projectData

            Write-Output "$($addCount) file(s) have been added to the project"
            Write-Output "$($duplicateCount) duplicate file(s) have been skipped"
            Write-Output "$($updatedCount) source file(s) have had their TAB locations updated."
        } #continue processing
    }
    End
    {
        if ( $continueProcessing -eq $true ) 
        {
        
        }
    }
}
<#
.Synopsis
   Create an empty .psproj file.
.DESCRIPTION
   In order to start populating a .psproj file with the Add and Remove commands one needs to have an existing .psproj because we are validating the existance of the file in all of the other commands in this module that take the -ProjectFile parameter.
.EXAMPLE
   PS> Create-PowershellProject ISEPSProject
   PS> Get-ChildItem ISEPSProject.psproj
 
 
    Directory: C:\Powershell\ISEPSProject
 
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/28/2016 7:57 AM 912 ISEPSProject.psproj
 
.EXAMPLE
When the file exists with the .psproj extension, and we only specify the basename, we will fail with a warning.
 
PS> dir
 
 
    Directory: C:\Powershell\ISEPSProject
 
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/28/2016 7:28 AM 1993 Add-SourceToPowershellProject.ps1
-a---- 12/27/2016 8:04 PM 1865 Clean-PowershellProject.ps1
-a---- 12/27/2016 7:46 PM 1715 Compare-PowershellProjectBackup.ps1
-a---- 12/28/2016 7:44 AM 1207 Create-PowershellProject.ps1
-a---- 12/28/2016 7:17 AM 691 Get-PowershellProject.ps1
-a---- 12/27/2016 7:45 PM 916 Get-PowershellProjectBackup.ps1
-a---- 12/28/2016 7:44 AM 912 ISEPSProject.psproj
-a---- 12/28/2016 7:23 AM 2035 Open-PowershellProject.ps1
-a---- 12/28/2016 7:29 AM 2135 Remove-SourceFromPowershellProject.ps1
 
PS> Create-PowershellProject ISEProject
WARNING: After adding .psproj extension to the chosen filename, we have determined the file already exists.
.EXAMPLE
When we specify a project file with the extension, and it already exists, we will fail via the ValidationScript.
 
PS> Create-PowershellProject ISEPSProject.psproj
Create-PowershellProject : Cannot validate argument on parameter 'ProjectFile'. The " -Not (Test-Path $_) " validation script for the argument with value "ISEPSProject.psproj" did not return a result of True.
Determine why the validation script failed, and then try the command again.
At line:1 char:26
+ Create-PowershellProject ISEPSProject.psproj
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [Create-PowershellProject], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Create-PowershellProject
  
#>

function Create-PowershellProject
{
    [CmdletBinding()]
    Param
    (
        # Specify the project file to open.
        [Parameter(Mandatory=$true,
                   Position=0)]
        [Alias('File','FilePath')]
        [ValidateScript({ -Not (Test-Path $_) })]
        [string]
        $ProjectFile
    )

    Begin
    {
        $baseName = [System.IO.Path]::GetFileNameWithoutExtension($ProjectFile)
        $extension = [System.IO.Path]::GetExtension($ProjectFile)

        $ProjectFileToCreate = "$($baseName).psproj"

        Write-Verbose "Checking for the existance of the filename with the .psproj extension: $($ProjectFileToCreate)"
        if ( Test-Path $ProjectFileToCreate ) 
        {
            Write-Warning "After adding .psproj extension to the chosen filename, we have determined the file already exists."
            break;
        }

    }
    Process
    {
        $projectData = @{"$($ProjectFileToCreate)"="$($ProjectFileToCreate)";"ISEPSProjectDataVersion"="$((Get-PowershellProjectCurrentVersion).CurrentVersion)"}
        $projectData | Export-Clixml -Path $ProjectFileToCreate -Force
    }
    End
    {
    }
}