Creating powershell array - powershell

I am a newby to powershell and am trying to automate a complex process. I need to copy and paste a 3 columns of data from one spreadsheet to a second one which will then be exported to an SAP transaction line by line. In my search I found the link below that discusses using $arr1 = #(0) * 20 to create the array. I have two questions.
The first question is what is the (0) referencing?
Also, using this formula how do I reference the workbook, sheet, and column that I need to use to create the array? Any help would be greatly appreciated.
PowerShell array initialization

#() is an array literal (typically used to define empty or single element array)
You can also use list object (System.Collection.ArrayList), might be more convenient since it has dynamic size.
Below is a quick and dirty example with COM object (reads data from range into array list)
$excel= new-object -com excel.application
$excel.Visible = $false
$wb = $excel.workbooks.open("$home\Documents\book1.xlsx")
$ws = $wb.Sheets.Item("Sheet1")
$data = New-Object System.Collections.ArrayList
foreach ($i in 1..20){
$data.Add( (New-Object PSObject -Property #{A=$ws.Range("A$i").Value2; B=$ws.Range("B$i").Value2}) ) | Out-Null
}
Write-Output $data
$wb.Close()

Related

how to create dynamic link list from .lnk files in a folder with powershell

I would like to be able to create a dynamic link list from .lnk files in a folder with powershell. I want the link list to be presented to the user in a form that can be minimzed, but will stay active for the entire session, even if the user launch one of them the main form will remain active.
I'm having a hard time moving from VBS to powershell, so any help would be appreciated.
Finally I have managed to have a begining of solution here is my code.
$linklist = #(
("MyFisrtApp" , "\\Path\To\MyFisrtApp.exe"),
("MySecondApp" , "\\Path\To\MySecondApp.exe"),
("MyThirdApp" , "\\Path\To\MyThirdApp.exe"),
("MyFourthApp" , "\\Path\To\MyFourthApp.exe")
)
#Create Form Object
$mainform = New-Object System.Windows.Forms.Form
$mainform.Size = New-Object System.Drawing.Size(400,300)
$mainform.Text = " My Virtual Applications"
$mainform.StartPosition = "CenterScreen" #loads the window in the center of the screen
# convert the array of arrays into an ordered Hashtable
$linkHash = [ordered]#{}
$linklist | ForEach-Object { $linkHash[$_[0]] = $_[1] }
$calculatedPosition =40
$linkHash.GetEnumerator() | ForEach-Object {
$lnk = New-Object System.Windows.Forms.LinkLabel
$lnk.Text = $_.Name # set the name for the label
$lnk.Tag = $_.Value # store the link url inside the control's Tag property
$lnk.Location = New-Object System.Drawing.Point(60, $calculatedPosition)
# inside the scriptblock, $this refers to the LinkLabel control itself
$lnk.Add_Click({ Start-Process $this.Tag })
$mainform.Controls.Add($lnk)
$calculatedPosition += 40 # just a guess, you may want different vertical spacing
}
#Show Form
$mainform.ShowDialog()
My next move now is to display the icon of the .lnk file on the left of each link and also dynamically construct the linklist hashtable from the properties of a list of .lnk files in a specific folder. Also having the form to auto-size as needed if more links need to be shown, would be interesting. I'm trying different setting with mitigated results.

Parsing Word Document using Powershell

I have to write a powershell script that can parse word document. Specifically, it has to read text from textboxes and store it in a variable. I know how to read text e.g. from a paragraph, but I don't know how to deal with textboxes. I would appreciate a sample.
Here is a part of my code:
$Word = New-Object -comobject Word.Application
$Word.Visible = $False
$datasheet = $word.Documents.Open($files[$i].FullName)
$value = ....?
Here is a screenshot of the box I need to read from:
Enumerate the contents of the Shapes collection and filter for shapes of the msoTextBox type (17):
$datasheet.Shapes |Where-Object {$_.Type -eq 17} |ForEach-Object {
# copy $_.TextFrame.TextRange.Text to wherever you need it in here
# $_.TextFrame.TextRange is a range object like any other (useful if you need formatting details or raw XML for example)
}

Columns Page Layout in Word with Powershell

I'm creating a word document with Powershell and I need to create a two-column column similar to the GUI method shown in the screen shot below:
I've researched other websites that explain basic Powershell Word objects, properties and methods, such as this one. However, there seems to be a lot more functionality that is "hidden" deep in the pages and pages of properties and methods. I'm looking to create a two-column column in my word doc. Here is the code I used to create the document and write to it:
$fileName = 'C:\template.docx'
$word = New-Object -Com Word.Application
$word.Visible = $true
$document = $word.Documents.Open($fileName)
$selection = $word.Selection
$text = "Test Text."
$selection.TypeText($text)
$document.SaveAs($fileName)
$document.Close()
$word.Quit()
$word = $null
Having worked with Excel ComObjects, it's not the easiest to figure out how to make it work with PowerShell.
You're missing this line:
$selection.PageSetup.TextColumns.SetCount(2)
How to get there?
Check the Word Interop Com Object MSDN page
It's probably the PageSetup object we're interesting in (because in the GUI the two columns appear under Layout > Page Setup > Columns)
Googling "word com object pagesetup" leds to a better MSDN documentation page that lists the properties
Repeat this process for TextColumns - it has the methods in the "Remarks" but I prefer to a doc page which lists the members
Finally, finding the SetCount method.
Hopefully this helps you to figure out how to navigate the Word ComObject document in future. The examples are in VBA or C# at best and need to be translated to PowerShell.
$fileName = 'C:\Template.docx'
$binding = "System.Reflection.BindingFlags" -as [type]
$word = New-Object -Com Word.Application
$word.Visible = $true
$document = $word.Documents.Open($fileName)
$selection = $word.Selection
$text = "Test Text."
$selection.TypeText($text)
$selection.PageSetup.TextColumns.SetCount(2)
# check the GUI here.
# You will see the Layout > Page Setup > Columns > Two is selected
$document.SaveAs($fileName)
$document.Close()
$word.Quit()
$word = $null

Powershell CheckedListBox check if in string / array

I've started learning Powershell and am now stuck after spending several hours on a problem I can find solutions for in multiple languages except Powershell.
I need to place a check against each item in a CheckedListBox that matches any of the values in a semi-colon delimited string named $MLBSVar_SelectedPackages. (eg. $MLBSVar_SelectedPackages = 'packageA;packageB;packageC;') and so on.
I've come up with this line but it doesn't yet work. Please can you help me?
if ($MLBSVar_SelectedPackages -ne $null) {
ForEach ($PackageName in $MLBSVar_SelectedPackages) {
ForEach ($item in $clb_SC_AvailablePackages.Items) {
if ($item -eq $PackageName) {
$clb_SC_AvailablePackages.Item($PackageName).Checked = $true
}
}
}
}
I've also tried .SetItemCheckState([System.Windows.Forms.CheckState]::Checked) in place of .Checked. The (one) issue seems to be getting a handle on the list item in the final section as it seems to be passed as a string rather than object? I have a VBS background and would really appreciate the assistance.
I think what you're looking for is something like the following code. You can use the SetItemChecked() method of the CheckedListBox class to check an item at a particular index. I see that you have attempted to use SetItemCheckState(), but did not make mention of SetItemChecked().
# Import Windows Forms Assembly
Add-Type -AssemblyName System.Windows.Forms;
# Create a Form
$Form = New-Object -TypeName System.Windows.Forms.Form;
# Create a CheckedListBox
$CheckedListBox = New-Object -TypeName System.Windows.Forms.CheckedListBox;
# Add the CheckedListBox to the Form
$Form.Controls.Add($CheckedListBox);
# Widen the CheckedListBox
$CheckedListBox.Width = 350;
$CheckedListBox.Height = 200;
# Add 10 items to the CheckedListBox
$CheckedListBox.Items.AddRange(1..10);
# Clear all existing selections
$CheckedListBox.ClearSelected();
# Define a list of items we want to be checked
$MyArray = 1,2,5,8,9;
# For each item that we want to be checked ...
foreach ($Item in $MyArray) {
# Check it ...
$CheckedListBox.SetItemChecked($CheckedListBox.Items.IndexOf($Item), $true);
}
# Show the form
$Form.ShowDialog();
After running this code, you should be presented with a dialog that looks similar to the following screenshot.

Add AUTOTEXT to MS Word Document with Power Shell

I am working on a project where I need to add AUTOTEXT entries like the Page 1 of X listings to the header and footer of a Power Shell generated MS Word document. I have tried extracting ideas from the following C# examples, but I cannot seem to figure out how to make it work. I was curious if someone could share some code to help me with this.
A starting point. This function add page number to the footer of document passed as parameter ( used on word 2010):
function Add-PageFooter ([string]$Document) {
add-type -AssemblyName "Microsoft.Office.Interop.Word"
set-variable -name wdAlignPageNumberCenter -value 1 -option constant
$fc1 = "Page"
$word = New-Object -comobject Word.Application
$Word.Visible = $True
#$Word.Visible = $False
$fc2 = [ref] "" -as [Type]
$OpenDoc = $Word.Documents.Open($Document)
$c = $OpenDoc.Sections.Item(1).Footers.Item(1).PageNumbers.Add($wdAlignPageNumberCenter)
$range1 = $openDoc.Sections.Item(1).Footers.Item(1).range
$field1 = $OpenDoc.Fields.Add($range1, -1, $fc2)
$field1.Code.Text = $fc1
$field1.Update
#$OpenDoc.Close()
}
Another way is to create a Word Macro and execute from powershell:
$wd = new-object -comobject word.application # create a com object interface (word application)
$wd.documents.open("C:\word\test.doc") # open doc
$wd.run("Macro01") # exec macro named macro01 that add custom footer and/or header
$wd.quit() # exit application
The macro must be saved on normal.dot (normal.dotm for 2010 and above) to have it in all open documents.
In this way you can customize what you want in a word document and not just header/footer recording in a macro your actions in the docs.