Visio automation via PowerShell - powershell

I have a script that automates the a Visio diagram, i based my script on the official Office site: http://gallery.technet.microsoft.com/office/f77fb025-11ee-48f3-8409-9bb567a63fc3
Well to be honest i have no idea how to retrieve the values of the "shape data", this shape data is for example (Serial number, Building, Location, etc...) from the pc stencil.
I want to add and revise this values programatically, i ve checked the object model reference but without luck.
Can someone help me?
here is the code, it opens a visio document and adds a pc stencil to the drawing.
$application = New-Object -ComObject Visio.Application
$application.visible = $true
$documents = $application.Documents
$document = $documents.Add("Basic Network Diagram.vst")
$pages = $application.ActiveDocument.Pages
$page = $pages.Item(1)
$ComputerStencil = $application.Documents.Add("Computers and Monitors.vss")
$pc = $ComputerStencil.Masters.Item("PC")
$shape1 = $page.Drop($pc, 2.2, 6.8)
$shape1.Text = "Some text...."
Thanxs for your time!!

The Visio Automation library may help you:
Here's an example of how you can use it in C#. Using it in PowerShell should not be difficult.
var app = new IVisio.Application();
var doc = app.Documents.Add("");
var page = doc.Pages[1];
var shape1 = page.DrawRectangle(1, 1, 3, 4);
VisioAutomation.CustomProperties.CustomPropertyHelper.Set(shape1,"Hello","World");
var props = VisioAutomation.CustomProperties.CustomPropertyHelper.Get(shape1);
Using the Visio PowerShell Module, the code will look something like this:
Set-StrictMode -Version 2
$ErrorActionPreference = "Stop"
Import-Module Visio
$app= New-VisioApplication
$doc = New-VisioDocument
$stencil_net = Open-VisioDocument "Basic Network Diagram.vst"
$stencil_comp = Open-VisioDocument "Computers and Monitors.vss"
$pc_master = Get-VisioMaster "PC" $stencil_comp
$shapes = New-VisioShape -Masters $pc_master -Points 2.2,6.8
Set-VisioText "Some Text..."
Set-VisioCustomProperty -Name "prop1" -Value "val1"
Set-VisioCustomProperty -Name "prop2" -Value "val2"
$shapedata_col = Get-VisioCustomProperty -Shapes $shapes
foreach ($shapedata in $shapedata_col)
{
Write-Host "--------------------------------------"
Write-Host Name $shapedata.Name
Write-Host Type $shapedata.Type
Write-Host Value $shapedata.Value
Write-Host Prompt $shapedata.Prompt
Write-Host Ask $shapedata.Ask
Write-Host Calendar $shapedata.Calendar
Write-Host Format $shapedata.Format
Write-Host Invisible $shapedata.Invisible
Write-Host Label $shapedata.Label
Write-Host LangId $shapedata.LangId
Write-Host ShapeID $shapedata.ShapeID
Write-Host SortKey $shapedata.SortKey
}
At the bottom you can see how to set and retrieve shape data.

You could also export the drawing as html, then parse the resulting data.xml.

Related

Powershell PowerPoint Header

I have a simple script that creates a Word Document and a PowerPoint document for staff that are sitting an exam where the files needed are pre loaded to a user area on a file share. The Word Document opens an creates the document header with the line of code
$Header = $Section.Headers.Item(1);
$Header.Range.Text = "$FirstName $SecondName $ID Activity 1";
PowerPoint is a bit more funnier and when you add a header it asks for dates. Is there a way to do this with powershell? We are printing them afterwards so would be a lot more benificial to have the variables that are in the CSV printed in the header of the document.
If this isn't doable is there a way to edit the first slide to have the variables in the first slide of the PowerPoint.
If anyone is able to look at the code or any ways of simplifying it, it would be massively appreiciated
The CSV is listed below and the full script is at the bottom :)
ID Four First Second
219999 9999 Tech Support
Have a good day
$Exams = Import-Csv "C:\\techtest.csv"
$fileserver = "C:\\ExamHomes\"
foreach ($User in $Exams)
{
$FirstName = $User.First
$SecondName = $User.Second
$ID = $User.ID
$FourID = $User.Four
$Time = "am"
$Date = "1511"
$Word = New-Object -ComObject Word.Application;
$Word.Visible = $false;
$Doc = $Word.Documents.Add();
$Section = $Doc.Sections.Item(1);
$Header = $Section.Headers.Item(1);
$Header.Range.Text = "$FirstName $SecondName $ID Activity 1";
$Doc.SaveAs("$fileserver\${date}${time}-${FourID}\Desktop\activity 1_${ID}_${FirstName}_${SecondName}.docx");
$Word.Quit()
Write-Host "File 'activity 1_${ID}_${FirstName}_${SecondName}.docx' for $FirstName $SecondName has been created and sent to the folder ${date}${time}-${FourID}" -BackgroundColor Black -ForegroundColor Cyan
add-type -assembly microsoft.office.interop.powerpoint
$Application = New-Object -ComObject powerpoint.application
$slideType = "microsoft.office.interop.powerpoint.ppSlideLayout" -as [type]
$presentation = $application.Presentations.add()
$presentation.SaveAs("$fileserver\${date}${time}-${FourID}\Desktop\activity 1_${ID}_${FirstName}_${SecondName}.pptx")
$presentation.close()
Stop-Process -name POWERPNT -Force
Write-Host "File 'activity 1_${ID}_${FirstName}_${SecondName}.pptx' for $FirstName $SecondName has been created and sent to the folder ${date}${time}-${FourID}" -BackgroundColor Black -ForegroundColor Cyan
}
Write-Host "All Staff have successfully had their document deployed for the exam" -BackgroundColor Black -ForegroundColor Red
Headers are only available for Notes Master and Handout Master objects
But you can add a Footer on a slide.
Add-Type -AssemblyName microsoft.office.interop.powerpoint
$Application = New-Object -ComObject powerpoint.application
$presentation = $application.Presentations.add()
$slide = $presentation.Slides.Add(1, [Microsoft.Office.Interop.PowerPoint.PpSlideLayout]::ppLayoutTitle)
$slide.Shapes.Title.TextFrame.TextRange.Text = "My Title"
$slide.Shapes(2).TextFrame.TextRange.Text = "My SubTitle"
$slide.HeadersFooters.Footer.Visible = $true
$slide.HeadersFooters.Footer.Text = "My Name"
You can use some Text on the DateAndTime HeaderFooter object like this:
$slide.HeadersFooters.DateAndTime.Visible = $true
$slide.HeadersFooters.DateAndTime.UseFormat = $true
$slide.HeadersFooters.DateAndTime.Format = [Microsoft.Office.Interop.PowerPoint.PpDateTimeFormat]::ppDateTimeFigureOut
$slide.HeadersFooters.DateAndTime.Text = "Coucou"
EDIT: SLIDE MASTER
In fact this can be defined on the SlideMaster so that every Slide inherit the values from the footer, pagenumber or datetime.
This is defined at the presentation level. So depending what you want do it on the SlideMaster or on any Slide you create. Probably a Slide may override the values from the SlideMaster.
$presentation.SlideMaster.HeadersFooters.SlideNumber.Visible = $true
$presentation.SlideMaster.HeadersFooters.Footer.Visible = $true
$presentation.SlideMaster.HeadersFooters.Footer.Text = "My Name"
$presentation.SlideMaster.HeadersFooters.DateAndTime.Visible = $true
$presentation.SlideMaster.HeadersFooters.DateAndTime.UseFormat = $true
$presentation.SlideMaster.HeadersFooters.DateAndTime.Format = [Microsoft.Office.Interop.PowerPoint.PpDateTimeFormat]::ppDateTimeFigureOut
$presentation.SlideMaster.HeadersFooters.DateAndTime.Text = "Something"

Send Outlook Task Reminder Using Powershell

I wish to send an email outlook task with reminder by using powershell, is that possible? The task similar as image below:
Is powershell built in function able to create this task instead of create a normal email using "new-object Net.Mail.MailMessage"? Any sample code/documentation to refer?
A quick google search brought up these
https://blogs.technet.microsoft.com/heyscriptingguy/2008/02/21/hey-scripting-guy-how-can-i-set-a-reminder-on-all-my-office-outlook-appointments/
http://www.leeholmes.com/blog/2007/03/01/getting-things-done-outlook-task-automation-with-powershell/
http://www.amandhally.net/2013/08/08/powershell-and-outlook-create-calendar-meetings-using-powershell-function/
No, that is not what the does. That is a .Net class as documented here.
Mail​Message Class
To use PowerShell with Outlook, you have to use the Outlook Object Model (DCOM). There are lots of examples of using PowerShell with Outlook all over the web. Doing a search will bring those up for you.
Here is just one example of dealing with Outlook Tasks with a few other references for you.
Managing an Outlook Mailbox with PowerShell
Getting Things Done – Outlook Task Automation with PowerShell
## Add-OutlookTask.ps1
## Add a task to the Outlook Tasks list
param( $description = $(throw "Please specify a description"), $category, [switch] $force )
## Create our Outlook and housekeeping variables.
## Note: If you don't have the Outlook wrappers, you'll need
## the commented-out constants instead
$olTaskItem = "olTaskItem"
$olFolderTasks = "olFolderTasks"
#$olTaskItem = 3
#$olFolderTasks = 13
$outlook = New-Object -Com Outlook.Application
$task = $outlook.Application.CreateItem($olTaskItem)
$hasError = $false
## Assign the subject
$task.Subject = $description
## If they specify a category, then assign it as well.
if($category)
{
if(-not $force)
{
## Check that it matches one of their already-existing categories, but only
## if they haven't specified the -Force parameter.
$mapi = $outlook.GetNamespace("MAPI")
$items = $mapi.GetDefaultFolder($olFolderTasks).Items
$uniqueCategories = $items | Sort -Unique Categories | % { $_.Categories }
if($uniqueCategories -notcontains $category)
{
$OFS = ", "
$errorMessage = "Category $category does not exist. Valid categories are: $uniqueCategories. " +
"Specify the -Force parameter to override this message in the future."
Write-Error $errorMessage
$hasError = $true
}
}
$task.Categories = $category
}
## Save the item if this didn't cause an error, and clean up.
if(-not $hasError) { $task.Save() }
$outlook = $null
See also this module:
Powershell and Outlook: Create a New Outlook Task using Powershell OutlookTools Module
https://github.com/AmanDhally/OutlookTools

Setting the "Description" on a Document Library using PnP PowerShell for SharePoint Online

I am trying to set the description on a Document Library in SharePoint Online using the PnP-PowerShell Commands, but it seems to be very intermittent in working, so I wanted to check what the correct way to do it is?
I create a new library with:
New-PnPList -Template DocumentLibrary -Title "TempLibrary"
Then try to set the Description with:
$l = Get-PnPList -Identity TempLibrary
$l.Description = "My Description Here"
Now clearly that doesn't work since I need to send the changes back with CSOM I assume?
So then I tried the following:
$ctx = Get-PnPContext
$l = Get-PnPList -Identity TempLibrary
$l.Description = "My Description Here"
$ctx.ExecuteQuery()
But this still didn't seem to work.
Any thoughts anyone has on how to do this reliably would be greatly appreciated.
Many thanks,
D.
UPDATE
Eurgh... This seems to work, but is this right? Is it expected? Doesn't feel very PowerShell like...
New-PnPList -Title "Test5" -Template DocumentLibrary
$t = Get-PnPList -Identity Test5
$ctx.Load($t)
$ctx.ExecuteQuery()
$t.Description = "Test5 Description"
$t.Update()
$ctx.ExecuteQuery()
Without loading the list you will not be able to set the description or other properties so the code is correct.
$ctx.Load($t)
Why do you think this is not PS like? :) Curious...
Use the following script. Hope it helps.
Add - PSSnapin Microsoft.SharePoint.PowerShell
function CreateList($spWeb, $listName)
{
$spTemplate = $spWeb.ListTemplates["Document Library"]
$spListCollection = $spWeb.Lists
$spListCollection.Add($listName, $listName, $spTemplate)
}
Function SetDescription($spWeb, $listName)
{
$path = $spWeb.url.trim()
$spList = $spWeb.GetList("$path/Lists/$listName")
$spList.Description = "--Your Desired Description--"
$spList.Update()
}
$siteCollectionUrl = "--Your Site Collection Url--"
$listName = "--Your Desired List Name--"
$spWeb = Get - SPWeb - Identity $siteCollectionUrl
CreateList $spWeb $listName
SetDescription $spWeb $listName

Change printer paper tray settings via powershell

I attempted to use the WMI-Object to change the paper tray settings in powershell. However I've just learned that the value i'm trying to change is read-only apprently. Could someone help me accomplish task via powershell or VBScript?
$printers = Get-WMIObject -Class Win32_PrinterConfiguration | Where-Object {$_.Name -EQ "CHK.Checks"}
$printers.MediaType = 270
$printers.Put()
I attempted this and it did not work.
Please help!
Thanks in advance!
Since the value is read-only you won't be able to use WMI to set that. .Net has the System.Printing has an input bin setting, which isn't perfect but works. I've made a function around this in my PSPrintTools module. I think Tray1, Tray2 work as values as well, but I don't remember off the top of my head. Outside of this then you get into editing the PrintTicket XML. Here's the relevant code for just that feature:
$Printer = "Example Printer Name"
$InputBin = "AutoSelect","AutoSheetFeeder","Cassette","Manual","Tractor" #choose one
Add-Type -AssemblyName System.Printing
$Permissions = [System.Printing.PrintSystemDesiredAccess]::AdministrateServer
$QueuePerms = [System.Printing.PrintSystemDesiredAccess]::AdministratePrinter
$PrintServer = new-object System.Printing.LocalPrintServer -ArgumentList $Permissions
$NewQueue = New-Object System.Printing.PrintQueue -ArgumentList $PrintServer,$Printer,1,$QueuePerms
$InputBinCaps = $NewQueue.GetPrintCapabilities().InputBinCapability
if ($null -ne $InputBinCaps) {
if ($InputBinCaps.Contains([System.Printing.InputBin]::$InputBin)) {
$NewQueue.DefaultPrintTicket.InputBin = [System.Printing.InputBin]::$InputBin
$NewQueue.UserPrintTicket.InputBin = [System.Printing.InputBin]::$InputBin
} else {
Write-Error "$InputBin unavailable on $Printer"
}
}
$NewQueue.commit()
$NewQueue.dispose()
$PrintServer.commit()
$PrintServer.dispose()

SharePoint Online Powershell CSOM create list from custom template

All,
I am trying to create a list using a custom list template that includes content for SharePoint Online using powershell and CSOM. The list template for now is already loaded into the site collection. If I go through the UI, I can create the list on a site using the template including content without issue. If I try to do it through powershell, the list gets created but without the columns and or contents.
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword)
$clientContext.Credentials = $credentials
if (!$clientContext.ServerObjectIsNull.Value)
{
Write-Host "Connected to SharePoint Online site: '$Url'" -ForegroundColor Green
}
$web = $clientContext.Web
$templates = $clientContext.Site.GetCustomListTemplates($web)
$clientContext.Load($templates)
$clientContext.ExecuteQuery()
$template = $templates | Where-Object{ $_.Name -eq "SomeTemplate" }
$lci = New-Object Microsoft.SharePoint.Client.ListCreationInformation
$lci.Title = "Some List"
$lci.TemplateFeatureId = $template.FeatureId
$lci.TemplateType = $template.ListTemplateTypeKind
$lci.DocumentTemplateType = $template.ListTemplateTypeKind
$lists = $clientContext.Web.Lists;
$clientContext.Load($lists);
$clientContext.ExecuteQuery();
$list = $lists.Add($lci)
$list.Update()
$clientContext.ExecuteQuery()
I can't figure out what is missing, any help would be much appreciated.
I think you have to associate Fields to Content Type (CT) and then add this CT to your List.
Try look at this:
http://www.sharepointfire.com/2016/01/create-new-content-type-sharepoint-online-powershell/
In previous step he created Columns(Fields) which he used in creation:
$columns = "BlogNumber", "BlogText", "BlogUser"
Hope it will help you.
Alex
I Think you have to add the list template before update. It works for me
...
$lci.Title = "Some List"
$lci.TemplateFeatureId = $template.FeatureId
$lci.TemplateType = $template.ListTemplateTypeKind
$lci.DocumentTemplateType = $template.ListTemplateTypeKind
$lci.ListTemplate = $template
...