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 { } } |