############################################################### # User Defined Settings ############################################################### $global:CatalogName = 'ApplicationCatalog' #Name of AdminStudio catalog $SQLUserName = 'DBacct' #AdminStudio catalog user who should have access to the catalog (sql server) $SQLPassword = 'DBpwd' #Password for this user $SQLServer = '10.10.10.10' #Sql server name or ip $SCCMServer = '10.10.10.10' #ConfigMgr (SCCM) name or ip $SCCMServerSiteCode = 'FLX' #ConfigMgr site code $SCCMRepositoryPath = '10.10.10.10\SCCMPublish' #ConfigMgr content location(a shared folder) $SCCMTargetGroup = 'Applications' #ConfigMgr destination foldeer where the applications will be created $SCCMUser = 'CMacct' #ConfigMgr username $SCCMPass = 'CMpwd' #ConfigMgr password $DistributionName = 'ConfigMgr' #Connection name that will be added in AdminStudio $ShareUser = 'CMacct' #Username having access to content location $SharePwd = 'CMpwd' #Password for this username ##################################################################### # Non-User Settings ##################################################################### $ConnectionString = 'PROVIDER=SQLOLEDB.1;Data Source=' + $SQLServer+';Initial Catalog=' + $global:CatalogName + ';user ID='+$SQLUserName+';password='+$SQLPassword+'' $shive = "HKLM:\SOFTWARE\Wow6432Node\InstallShield\AdminStudio\18.0\" $slocation = "Product Location" $sAsLoc = (Get-ItemProperty $shive $slocation).$slocation $sCurrentLoc = [Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath $sAsLoc = $sAsLoc + "Common\" $SCCMPluginID = 13 $Global:CSVFilePath = $null $Global:ProductColumnName = $null $Global:VendorColumnName = $null $Global:VersionColumnName = $null $Global:CSVContent = $null ##################################################################### # Functions ##################################################################### function LoadDLL ($s) { $FileName = $sAsLoc + $s import-module -name $FileName } function PrepAS () { LoadDLL 'AdminStudio.Platform.PowerShellExtensions.dll' LoadDLL 'AdminStudio.Utilities.dll' LoadDLL 'AdminStudio.SCCM.Model.dll' LoadDLL 'AdminStudio.SCCM.Integrator.dll' Set-ASConfigPlatform -ConnectionString $ConnectionString $sync = Invoke-ASPackageFeedSync } function ProcessInputCSV() { [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null $csvfilepath = [Microsoft.VisualBasic.Interaction]::InputBox("Enter CSV File Path", "CSV File Path") try{ if (Test-Path $csvfilepath -ErrorAction Stop) { $Global:CSVFilePath = $csvfilepath } else { Write-Host 'File not found. Please run the script again with the correct file path!' -ForegroundColor Red Exit } } catch { Write-Host 'File not found. Please run the script again with the correct file path!' -ForegroundColor Red exit } $CSVContent = Import-Csv $csvfilepath $Columns = $CSVContent[0].psobject.Properties.Name $ProductColumnName = SelectFromDropDown 'Product Name' $Columns If ($ProductColumnName -eq $null) { Write-Host 'Make a selection for Product Name column. Exiting script!' -ForegroundColor Red Exit } $VendorColumnName = SelectFromDropDown 'Vendor Name' $Columns If ($VendorColumnName -eq $null) { Write-Host 'Make a selection for Vendor Name column. Exiting scrtip!' -ForegroundColor Red Exit } $CSVContent | Select-Object *,"SearchResult","MatchedProductName","MatchedVersion","SelectedProductName","SelectedVersion","SelectedPkgFid" -ErrorAction Ignore| Export-Csv -Path $Global:CSVFilePath -Force -NoTypeInformation $Global:CSVContent = Import-Csv $csvfilepath $Global:ProductColumnName = $ProductColumnName $Global:VendorColumnName = $VendorColumnName } function SearchResults($ProductsList) { $ProductsList| ForEach-Object { $product = $_.$Global:ProductColumnName $vendor = $_.$Global:VendorColumnName $Search = Invoke-ASPackageFeedSearch -ProductName $product -Vendor $vendor $MatchedProductName = $null $MatchedVersion = $null $fids = $null if ($Search -like '*No matching records found*') { $_.SearchResult = 'Sorry, no match found' $_.MatchedProductName = 'Not found' $_.MatchedVersion = 'Not found' $_.SelectedProductName = 'Not found' $_.SelectedVersion = 'Not found' $_.SelectedPkgFid = 'Not found' $ProductsList |Export-Csv -Path $Global:CSVFilePath -Force -NoTypeInformation } else{ if ($Search.Count -gt 1) {$_.SearchResult = 'Matches Found'} else {$_.SearchResult = 'Match Found'} for ($i=0; $i -lt $Search.Count; $i++) { $MatchedProductName= $MatchedProductName + $Search.Item($i).ProductName+"`n" $MatchedVersion= $MatchedVersion + $Search.Item($i).Version+"`n" $_.MatchedProductName = $MatchedProductName $_.MatchedVersion = $MatchedVersion } $_.SelectedProductName = $Search.Item(0).ProductName $_.SelectedVersion = $Search.Item(0).Version $_.SelectedPkgFid = $Search.Item(0).PackageFeedId $ProductsList |Export-Csv -Path $Global:CSVFilePath -Force -NoTypeInformation } if (!($Search -like '*No matching records found*')){ $fids = $Search.Item(0).PackageFeedId return $fids } } } function ExecuteSQLQuery($strSQLQuery) { $retval=-1 $temp = '' $adapter = '' $command = '' $dataset = '' $Value = @() $result = '' $strSQLQuerySplit = '' If($strSQLQuery) { $ConnectionInfo = 'Data Source=' + $SQLServer+';Initial Catalog=' + $global:CatalogName + ';user ID='+$SQLUserName+';password='+$SQLPassword+'' $connection = new-object system.data.SqlClient.SQLConnection($connectionInfo) $command = new-object system.data.sqlclient.sqlcommand($strSQLQuery,$connection) $connection.Open() $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command $dataset = New-Object System.Data.DataSet $temp= $adapter.Fill($dataSet) $result= $dataset.Tables $strSQLQuerySplit = $strSQLQuery.split() if(($strSQLQuerySplit.item(0) -eq "select")) { if($strSQLQuerySplit[1].Contains(",")) { for($row=0; $row -lt $result[0].Rows.Count;$row++) { $Value+= $result[0].rows[$row].ItemArray+"`n" $retval=$Value } } else { $Value = $result[0].Columns[0].ColumnName if(![string]::IsNullOrEmpty($result.$Value)) { $retval = ([string]$result.$Value).trim() } else { $retval= $result.$Value #Some select queries return null values } } } else { $retval = 0 } $connection.Close() } return $retval } function SelectOptions ($Option1,$Option2) { [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") $Form = New-Object System.Windows.Forms.Form $Form.width = 500 $Form.height = 300 $Form.Text = ”Select an option" $Form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen $WrapOptionsGrp = New-Object System.Windows.Forms.GroupBox $WrapOptionsGrp.Location = '40,30' $WrapOptionsGrp.size = '400,150' $Opt1Btn = New-Object System.Windows.Forms.RadioButton $Opt1Btn.Location = '20,40' $Opt1Btn.size = '350,30' $Opt1Btn.Checked = $true $Opt1Btn.Text = $Option1 $Opt2Btn = New-Object System.Windows.Forms.RadioButton $Opt2Btn.Location = '20,70' $Opt2Btn.size = '350,30' $Opt2Btn.Checked = $false $Opt2Btn.Text = $Option2 $OKBtn = new-object System.Windows.Forms.Button $OKBtn.Location = '130,200' $OKBtn.Size = '80,30' $OKBtn.Text = 'OK' $OKBtn.DialogResult=[System.Windows.Forms.DialogResult]::OK $CancelBtn = new-object System.Windows.Forms.Button $CancelBtn.Location = '255,200' $CancelBtn.Size = '80,30' $CancelBtn.Text = "Cancel" $CancelBtn.DialogResult=[System.Windows.Forms.DialogResult]::Cancel $form.Controls.AddRange(@($WrapOptionsGrp,$OKBtn,$CancelBtn)) $WrapOptionsGrp.Controls.AddRange(@($Opt1Btn,$Opt2Btn)) $form.AcceptButton = $OKBtn $form.CancelButton = $CancelBtn $form.Add_Shown({$form.Activate()}) $dialogResult = $form.ShowDialog() if ($dialogResult -eq "OK"){ if ($Opt1Btn.Checked){ $OptionSelected = $Option1 } elseif ($Opt2Btn.Checked){ $OptionSelected = $Option2 } return $OptionSelected } else { $OptionSelected = $null return $OptionSelected } } function SelectTasks() { $TasksList = "Import", "Test","Wrap","PublishToSCCM" $formTitle="Select Tasks" $Form = New-Object System.Windows.Forms.Form $btnCancel = New-Object System.Windows.Forms.Button $btnNext = New-Object System.Windows.Forms.Button $cloCheckList = New-Object System.Windows.Forms.CheckedListBox $btnMargin = New-Object System.Windows.Forms.Padding(4,4,4,4) $btnSize = New-Object System.Drawing.Size(80,30) $Form.SuspendLayout() $btnCancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $btnCancel.Location = New-Object System.Drawing.Point(246, 134) $btnCancel.Margin = $btnMargin $btnCancel.Size = $btnSize $btnCancel.Text = "Cancel" $btnNext.DialogResult = [System.Windows.Forms.DialogResult]::OK $btnNext.Location = New-Object System.Drawing.Point(246, 83) $btnNext.Margin = $btnMargin $btnNext.Size = $btnSize $btnNext.Text = "OK" $cloCheckList.FormattingEnabled = $true $cloCheckList.Items.AddRange($TasksList) $cloCheckList.Location = New-Object System.Drawing.Point(12, 12) $cloCheckList.Size = New-Object System.Drawing.Size(227, 165) $Form.AcceptButton = $btnNext $Form.AutoScaleMode = [System.Windows.Forms.AutoScaleMode]::None $Form.CancelButton = $btnCancel $Form.ClientSize = New-Object System.Drawing.Size(376, 189) $Form.Margin = $btnMargin $Form.Name = "Form" $Form.Text = $formTitle $Form.MaximizeBox = $False $Form.MinimizeBox = $False $Form.ShowIcon = $true $Form.ShowInTaskbar = $true $Form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen $Form.TopMost = $True $Form.WindowState = [System.Windows.Forms.FormWindowState]::Normal $Form.Controls.Add($cloCheckList) $Form.Controls.Add($btnCancel) $Form.Controls.Add($btnNext) $Form.ResumeLayout($true) $result = $form.ShowDialog() if ($result -eq ([System.Windows.Forms.DialogResult]::OK)){ $selections += for($i=0; $i -lt $($cloCheckList.CheckedItems.Count); $i++){ $($cloCheckList.CheckedItems[$i]) } } else{ $selections = $null } If ($selections -eq $null) { Write-Host 'No tasks selected. Exiting Script!' -ForegroundColor Red Exit } If ($selections.contains('Wrap')) { $selectwrap = SelectOptions 'PowerShellWrapping' 'EXEWrapping' if ($selectwrap -eq $null) { Write-Host 'Make a selection for Wrapping Option. Exiting Script!' -ForegroundColor Red Exit } else { $selections -replace 'Wrap', $selectwrap } } else{$selections} } function AddDetectionMethod($PkgO,$DMFilePath,$DLFilePath, $DMPrimaryFileVersion) { $DMPrimaryFilePath = split-path $DMFilePath -Parent $DMPrimaryFileName = split-path $DMFilePath -leaf $xmlcontent = ' 0 None FileSystem File '+$DMPrimaryFilePath +' '+$DMPrimaryFileName+' false false Version IsEquals '+$DMPrimaryFileVersion+' ' $strSource= split-path $DLFilePath -Parent Set-Content $strSource\$ProdName.xml $xmlcontent $AddDM = Set-ASAppModelData -PackageId $PkgO.RowID -Type DetectionMethod -XmlPath $strSource\$ProdName.xml If ($AddDM -eq $null) { Write-Host $ProdName ': Adding Detection Method for this package failed. If there are no default detection methods, then Publish to ConfigMgr may fail' -ForegroundColor Red } Remove-Item -Path $strSource\$Prodname.xml } function DownloadSetupFile ($PackageFid, $SetupFile) { try{ $download = Invoke-ASPackageFeedDownload -PackageFeedId $PackageFid -FileName $SetupFile -ErrorAction Stop } catch { Write-Host 'Download may have failed:'$SetupFile -ForegroundColor Red $download = $null } return $download } function ProcessApplication($AppsList) { $pkgfids = SearchResults($AppsList) $Tasks = SelectTasks Foreach($pkgfid in $pkgfids){ $AppsList | ForEach-Object { if ($_.SelectedPkgFid -eq $pkgfid) { $SearchedProd = $_.$Global:ProductColumnName } } #To identify the product name from the csv file $PackageDetails = Get-ASPackageFeedDetails -PackageFeedId $pkgfid $SilentCmdLineSwitch = $PackageDetails.SilentCommandLineSwitches $SetupFileName=$PackageDetails.FileName $ProdName = $PackageDetails.ProductName $PFSoftVersion = $PackageDetails.Version $PrimaryFileVersion = $PackageDetails.PrimaryFileVersion $FilePath = $PackageDetails.PrimaryFile Foreach ($Task in $Tasks) { switch($Task){ Import { $ProdExistQuery = "Select * from cstblpackage where ProductName like '%$SearchedProd%'" $ProdExists = ExecuteSQLQuery $ProdExistQuery If ($ProdExists -ne $null) { $SoftVersionQuery = "Select ProductVersion from cstblpackage where ProductName like '%$SearchedProd%'" $SoftVersion = ExecuteSQLQuery $SoftVersionQuery $SoftVersionSplit = $SoftVersion.split() $maxVerion = ($SoftVersionSplit | Measure -Max).Maximum try{ If ([System.Version]$PFSoftVersion -gt [System.Version]$maxVerion) { $DownloadedFilePath = DownloadSetupFile $pkgfid $SetupFileName if ($DownloadedFilePath -ne $null) { $PkgObj = Import $DownloadedFilePath $SilentCmdLineSwitch if ($PkgObj -ne $null) { AddDetectionMethod $PkgObj $FilePath $DownloadedFilePath $PrimaryFileVersion } else { Write-Host 'Import may have failed for the setup file:' $DownloadedFilePath -ForegroundColor Red Break } } else { Write-Host 'Setup file not found. Download may have failed!' -ForegroundColor Red $PkgObj = $null Break } } else { Write-Host $ProdName ':AdminStudio catalog already has this setup file of either same or higher software version' -ForegroundColor Red $PkgObj = $null Break } } catch{ Write-Host $ProdName ':Error while comparing software version, importing the package anyway' -ForegroundColor Green $DownloadedFilePath = DownloadSetupFile $pkgfid $SetupFileName if ($DownloadedFilePath -ne $null) { $PkgObj = Import $DownloadedFilePath $SilentCmdLineSwitch if ($PkgObj -ne $null) { AddDetectionMethod $PkgObj $FilePath $DownloadedFilePath $PrimaryFileVersion } else { Write-Host 'Import may have failed for the setup file:' $DownloadedFilePath -ForegroundColor Red Break } } } } else { $DownloadedFilePath = DownloadSetupFile $pkgfid $SetupFileName if ($DownloadedFilePath -ne $null) { Write-Host $ProdName ': Package does not exist in catalog. Importing the package...' -ForegroundColor Green $PkgObj = Import $DownloadedFilePath $SilentCmdLineSwitch if ($PkgObj -ne $null) { AddDetectionMethod $PkgObj $FilePath $DownloadedFilePath $PrimaryFileVersion } else { Write-Host 'Import may have failed for the setup file:' $DownloadedFilePath -ForegroundColor Red Break } } else { Write-Host 'Setup file not found. Download may have failed!' -ForegroundColor Red $PkgObj = $null Break } } } Test { if ($PkgObj -ne $null) { Test ($PkgObj) } else { Write-Host $ProdName ':Cannot Test. Import may have failed for this package' -ForegroundColor Red Break } } PublishToSCCM { if ($PkgObj -ne $null) { Write-Host 'tasks' + $Tasks If ($Tasks.Contains("PowerShellWrapping") -or $Tasks.Contains("EXEWrapping")) { $PkgId = $PkgObj.RowID + 1 } else { $PkgId = $PkgObj.RowID } DistributePackage ($PkgId) } else { Write-Host $ProdName ':Cannot Publish. Import may have failed for this package' -ForegroundColor Red Break } } PowerShellWrapping { if ($PkgObj -ne $null) { Invoke-ASWrapPackage -PackageID $PkgObj.RowID -WrapType Ps1 } else { Write-Host $ProdName ':Cannot Wrap. Import may have failed for this package' -ForegroundColor Red Break } } EXEWrapping { if ($PkgObj -ne $null) { Invoke-ASWrapPackage -PackageID $PkgObj.RowID -WrapType Exe } else { Write-Host $ProdName ':Cannot Wrap. Import may have failed for this package' -ForegroundColor Red Break } } $null { Write-Host 'No tasks selected!' -ForegroundColor Red exit} } } } } function Test ($o) { Write-Host 'Testing Package:' $o.DisplayedProductName -nonewline -foregroundcolor white Write-Host ' RowId:' $o.RowID -foregroundcolor gray $oTestResults = Test-ASPackage -PackageId $o.RowID $errors = 0; $warn = 0; $fixable=0; foreach ($oTestResult in $oTestResults.Stats) { $errors = $errors + $oTestResult.Errors $warn = $warn + $oTestResult.Warnings } Write-Host-Indent Write-Host 'Errors:' $errors -foregroundcolor red Write-Host-Indent Write-Host 'Warnings:' $warn -foregroundcolor yellow Write-Host } function Import ($s, $SilentSwitch) { $f = [System.IO.File]::GetAttributes($s) $d = ($f -band [System.IO.FileAttributes]::Directory) if (!$d) { Write-Host 'Importing:' $s -foregroundcolor white $obj = Invoke-ASImportPackage -PackagePath $s -InstallCommandLine $SilentSwitch if ($obj.GetType().FullName -eq 'AdminStudio.Platform.Helpers.PackageHelper') { return $obj } else { Write-Host 'Failed to import:' $s -foregroundcolor red $obj = $null return $obj } } } function DistributePackage($PkgID) { New-ASDistributionConnection -Name $DistributionName -PluginID $SCCMPluginID -ServerAddress $SCCMServer -SiteCode $SCCMServerSiteCode -DistributionWindowsAuthentication 0 -DistributionUser $SCCMUser -DistributionPassword $SCCMPass -SharePath $SCCMRepositoryPath -ShareWindowsAuthentication 0 -ShareUserName $ShareUser -SharePassword $SharePwd Write-Host 'Distributing the Package:' $oPkg.DisplayedProductName -nonewline -foregroundcolor white Write-Host ' RowId:' $PkgID -foregroundcolor gray $oAppID = Get-ASApplicationID -PackageID $PkgID Invoke-ASPublish -ConnectionName $DistributionName -ApplicationID $oAppID ‑TargetGroup $SCCMTargetGroup } function SelectFromDropDown ($ColumnName,$arrName) { Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing $form = New-Object System.Windows.Forms.Form $form.Text = $ColumnName $form.Size = New-Object System.Drawing.Size(500,200) $form.StartPosition = 'CenterScreen' $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = New-Object System.Drawing.Point(75,120) $OKButton.Size = New-Object System.Drawing.Size(75,23) $OKButton.Text = 'OK' $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $OKButton $form.Controls.Add($OKButton) $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Point(150,120) $CancelButton.Size = New-Object System.Drawing.Size(75,23) $CancelButton.Text = 'Cancel' $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $CancelButton $form.Controls.Add($CancelButton) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size (400,20) $label.Text = 'Please select the column for: '+$ColumnName $form.Controls.Add($label) $DropDown = New-Object System.Windows.Forms.ComboBox $DropDown.Location = New-Object System.Drawing.Point(10,40) $DropDown.Size = New-Object System.Drawing.Size(260,20) $DropDown.Height = 80 ForEach ($Item in $arrName) { [void] $DropDown.Items.Add($Item) } $form.Controls.Add($DropDown) $form.Topmost = $true $result = $form.ShowDialog() if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $x = $DropDown.SelectedItem return $x } else { $x = $null return $x } } function Write-Host-Drawline () { Write-Host '**************************************' -foregroundcolor yellow } function Write-Host-Indent () { Write-Host ' ' -nonewline } ################################################################ # Main Loop ################################################################ cd $sAsLoc Write-Host Write-Host-Drawline Write-Host 'AdminStudio Directory =' $sAsLoc -foregroundcolor gray Write-Host 'Catalog Name=' $global:CatalogName -foregroundcolor gray Write-Host-Drawline Write-Host PrepAS ProcessInputCSV $Option = SelectOptions 'Search Apps' 'Process Apps' If ($Option -eq 'Search Apps') {SearchResults($Global:CSVContent)} elseif ($Option -eq 'Process Apps') {ProcessApplication($Global:CSVContent)} else {write-host 'Exiting the script. Please make a selection.' -ForegroundColor Red Exit } cd $sCurrentLoc ################################################################ # End ################################################################