Updating SharePoint User Profile Property with a Taxonomy Term - powershell

I'm experiencing a problem trying to update a SharePoint User Profile property that is linked to a taxonomy TermSet. The following code results in an exception.
$spsite = Get-SPSite $mysiteurl
$context = Get-SPServiceContext $mysiteurl
$upm = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
if ($upm.UserExists($adAccount))
{
$user = $upm.GetUserProfile($adAccount)
$locationsCollection = $user[$propName]
$taxMgr = new-object Microsoft.SharePoint.Taxonomy.TaxonomySession($spsite)
$taxStore = $taxMgr.TermStores[0]
$officeLocationsGroup = $taxStore.Groups["Office Locations"]
$officeLocationsTermSet = $officeLocationsGroup.TermSets["Office Locations"]
$terms = $officeLocationsTermSet.GetTerms($newValue, $false)
$foundTerm = $false
$newTerm = $null
foreach ($term in $terms) {
Write-Host " Found: $($term.Name)" -BackgroundColor Yellow -ForegroundColor Black
$foundTerm = $true
$newTerm = $term
}
if (-not $foundTerm) {
$newTerm = $officeLocationsTermSet.CreateTerm($theTermValue, 1033)
$foundTerm = $true
Write-Host " Created: $($newTerm.Name)" -BackgroundColor DarkGreen -ForegroundColor Black
$taxStore.CommitAll()
}
Write-Host "Adding the term..."
$locationsCollection.AddTaxonomyTerm($newTerm)
Write-Host "Term added."
$user.Commit()
Write-Host "Profile Committed."
}
The call to AddTaxonomyTerm triggers this exception:
Exception calling "AddTaxonomyTerm" with "1" argument(s): "Index was out of ran
ge. Must be non-negative and less than the size of the collection.
Parameter name: index"
At E:\mark\updateUserProfile.ps1:41 char:41
+ $locationsCollection.AddTaxonomyTerm <<<< ($newTerm)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Any thoughts on why this would occur would be of great help. Thanks.

It seems that you can't use the AddTaxonomyTerm method on empty fields. You need to "initialize" the taxonomy field first. Use the .Value method first, then the AddTaxonomyTerm method.
$locationsCollection.Value = $newTerm.Name;
$locationsCollection.AddTaxonomyTerm($newTerm)

Related

System.Printing.Addjob() Error in Powershell

So I am trying to create a script that will take a print job from one paused print queue and add it to an active queue. However I am trying to utilize the AddJob() function and upon calling it with or without parameters it returns an exception and I am not sure why. Here is what I have so far
$host.Runspace.ThreadOptions = "ReuseThread"
Add-Type -AssemblyName System.Printing
$permissions = [System.Printing.PrintSystemDesiredAccess]::AdministrateServer
$queueperms = [System.Printing.PrintSystemDesiredAccess]::AdministratePrinter
$server = new-object System.Printing.PrintServer -argumentList $permissions
$queues = $server.GetPrintQueues(#([System.Printing.EnumeratedPrintQueueTypes]::Shared))
foreach ($q in $queues) {
if ($q.IsPaused -eq 1)
{
$qPaused = new-object System.Printing.PrintQueue -argumentList $server,$q.Name,1,$queueperms
}
else
{
$qPlaying = new-object System.Printing.PrintQueue -ArgumentList $server,$q.Name,2,$queueperms
}
}
$byteContents = #('This is a test')
$byteContents | Out-File -FilePath "C:\testinput.txt"
[byte[]]$bytes = Get-Content -Encoding byte -Path "C:\testinput.txt"
#$printJob = $qPaused.GetJob(3).
$qPlaying.AddJob()
$jobStream = $printJob.JobStream
$jobStream | Out-GridView
#$jobStream.Write($bytes, 0, $bytes.Length)
#$jobStream.Close()
What this gives me is an error at the $qPlaying.AddJob() saying
Exception calling "AddJob" with "0" argument(s): "Specified argument was out of the range of valid values.
Parameter name: clientPrintSchemaVersion"
At line:23 char:1
+ $qPlaying.AddJob()
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentOutOfRangeException
Thank you for any feedback.
The version of the Print Schema is defined when you call the constructor for the queue in this line:
$qPlaying = new-object System.Printing.PrintQueue -ArgumentList $server,$q.Name,2,$queueperms
You are using PrintQueue Constructor (PrintServer, String, Int32, PrintSystemDesiredAccess) where the Int32 is the Print Queue Schema version. The MSDN article has a remark that: "The Print Schema version released with Windows Vista is "1"." Which would make sense that when you use 2 and receive an out of range error that 2 isn't an acceptable value.
You could use 1 as the value or use an alternate constructor. For example:
$qPlaying = new-object System.Printing.PrintQueue -ArgumentList $server,$q.Name,$queueperms

Install windows update

I have following powershell script which should update my windows OS everytime I run it. Therefore I use the given windows API in order to search, download and install the updates. But somehow only searching for them actually works.
This is my script:
$global:scriptpath = $MyInvocation.MyCommand.Path
$global:dir = Split-Path $scriptpath
$global:logfile = "$dir\updatelog.txt"
write-host " Searching for updates..."
$session = New-Object -ComObject Microsoft.Update.Session
$searcher = $session.CreateUpdateSearcher()
$result = $searcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
if ($result.Updates.Count -eq 0) {
Write-Host "No updates to install"
} else {
$result.Updates | Select Title
}
$downloads = New-Object -ComObject Microsoft.Update.UpdateColl
foreach ($update in $result){
try {
$update.AcceptEula()
$Null = $downloads.Add($update)
} catch {}
}
$count = $result.Updates.Count
write-host ""
write-host "There are $($count) updates available."
write-host ""
read-host "Press Enter to download\install updates"
$downloader = $session.CreateUpdateDownLoader()
$downloader.Updates = $downloads
$downloader.Download()
$installs = New-Object -ComObject Microsoft.Update.UpdateColl
foreach ($update in $result.Updates){
if ($update.IsDownloaded){
$installs.Add($update)
}
}
$installer = $session.CreateUpdateInstaller()
$installer.Updates = $installs
$installresult = $installer.Install()
$installresult
But I get following error:
Exception calling "Download" with "0" argument(s): "Exception from HRESULT: 0x80240024"
+ $downloader.Download()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
Somehow this line: $downloader.Updates = $downloads is not executed, but I don't know why. I also already tried running the script as an admin, didn't work either.
That error code is the WU_E_NO_UPDATE, described here. Basically it says that the Updates collection is not set or empty.

Exception calling "StartWorkflow" with "3" argument(s): ""

I am trying to write a powershell script that kicks off two workflows.
One needs to be kicked off only once while the other needs to be run on every item in the list. However I am being plagued by an error and I don't know how to get rid of it. When I add a 4 argument I get the same error. I am running the script as an spshelladmin
Error
Exception calling "StartWorkflow" with "3" argument(s): ""
At C:\cert.ps1:26 char: 29
+ $em = $manager.StartWorkFlow <<<< ($items[0],$emails,$data)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Code
$web = Get-SPWeb -Identity "http://portal.com/sites/it"
$manager = $web.Site.WorkFlowManager
$list = $web.Lists["Certificate Tracking"]
$assoc = $list.WorkflowAssociations.GetAssociationByName("Certificate Notification","en-US")
$assoc.AllowAsyncManualStart = $true
$assoc.AllowManual = $true
$emails = $list.WorkflowAssociations.GetAssociationByName("Status Update","en-US")
$emails.AllowAsyncManualStart = $true
$emails.AllowManual = $true
$view = $list.Views["All Items"] #All Items
$items = $list.GetItems($view)
$data = $assoc.AssociationData
$emData = $emails.AssociationData
$count = 0
foreach ($item in $items) {
$wf = $manager.StartWorkFlow($item,$assoc,$data)
}
$em = $manager.StartWorkFlow($items[0],$emails,$emData,$true)
$web.Dispose()
I actually discovered that a specific item I was targeting already had a workflow running on it, I did not place proper checks for the status (check out the comments on this code http://paulryan.com.au/2014/cancel-all-workflows/), very misleading error, I thought I had wrong overload with method call on StartWorkFlow ($item, $association, $data, $true), in SP 2013 there are 4 parameters not sure why the thread title says three... Anyways hope that helps someone.

Need help figuring out why Powershell is throwing error 16

I posted this script the other day in an effort to discover a good way to change file extensions when "saving as." I had the problem licked, but as of this morning, the script will not run without errors. Here's the error message I'm getting:
Processing : C:\users\xxx\Desktop\ht\Automatic_Post-Call_Survey.htm
Exception calling "SaveAs" with "16" argument(s): "This is not a valid file name.
Try one or more of the following:
* Check the path to make sure it was typed correctly.
* Select a file from the list of files and folders."
At C:\users\xxx\Desktop\hd.ps1:11 char:20
+ $opendoc.saveas <<<< ([ref]"$docpath\$doc.FullName.doc", [ref]$saveFormat);
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
if "16" is the error code, that represents an inability to delete the directory...but it doesn't appear as if I'm asking for that at all--unless there's some default parameter in place somewhere. I'm pretty much baffled.anyone have any other ideas I can try out?
$docpath = "c:\users\xxx\desktop\do"
$htmPath = "c:\users\xxx\desktop\ht"
$srcfiles = Get-ChildItem $htmPath -filter "*.htm*"
$saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], "wdFormatDocument");
$word = new-object -comobject word.application
$word.Visible = $False
$filename = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
function saveas-document {
$opendoc = $word.documents.open($doc.FullName);
$opendoc.saveas([ref]"$docpath\$filename", [ref]$saveFormat);
$opendoc.close();
}
ForEach ($doc in $srcfiles) {
Write-Host "Processing :" $doc.FullName
saveas-document
$doc = $null
}
$word.quit();
this should do what do you need, but is not the best design :)
$docpath = "c:\users\xxx\desktop\do"
$htmPath = "c:\users\xxx\desktop\ht"
$srcfiles = Get-ChildItem $htmPath -filter "*.htm*"
$saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], "wdFormatDocument");
$global:word = new-object -comobject word.application
$word.Visible = $False
#$filename = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
function saveas-document ($docs) {
$opendoc = $word.documents.open($docs);
$savepath = $docs -replace [regex]::escape($htmPath),"$docpath"
$savepath = $savepath -replace '\.html*', '.doc'
$opendoc.saveas([ref]"$savepath", [ref]$saveFormat);
$opendoc.close();
}
ForEach ($doc in $srcfiles) {
Write-Host "Processing :" $doc.FullName
saveas-document -doc $doc.FullName
$doc = $null
}
$word.quit();

Trouble adding a Workflow Activity to the Toolbox from a PowerShell Script

I’m creating a PowerShell Script (for NuGet) that can add System.Activities Workflow Activities to the Toolbox.
Currently I’m installing them with C# code written as a cmdlet but this causes problems when you try to uninstall the package since NuGet has the assembly loaded and it can’t be deleted.
My goal is to do everything from PowerShell so I don’t have to load the assembly. I’m very close except the last line where I add the toolbox item blows up with "Object must implement IConvertible." Which leads me to believe it thinks that something I’m passing to it is the wrong type.. I do know that the $toolbox interface is working because it does add a tab to the toolbox.
function AddActivity (
[string] $activity,
[string] $assemblyFullname,
[string] $name,
[string] $category,
[string] $bitmapPath)
{
Write-Host "Argument List"
Write-Host $activity
Write-Host $assemblyFullname
Write-Host $name
Write-Host $category
Write-Host $bitmapPath
Write-Host "Loading assemblies"
$assembly = [Reflection.Assembly]::Load("Microsoft.VisualStudio.Shell.Interop")
Write-Host "get the toolbox service"
Write-Host "get the toolbox service"
$ServiceType = [System.Type]::GetType("Microsoft.VisualStudio.Shell.Interop.SVsToolbox,{0}" -f $assembly.FullName)
$InterfaceType = [System.Type]::GetType("Microsoft.VisualStudio.Shell.Interop.IVsToolbox,{0}" -f $assembly.FullName)
$toolbox = Get-VSService $ServiceType $InterfaceType
Write-Host "Add a Tab"
$tlBoxTab = $toolbox.AddTab($category)
Write-Host "Create the DataObject"
$dataObject = New-Object Microsoft.VisualStudio.Shell.OleDataObject
$dataObject.SetData("AssemblyName", $assemblyFullname)
$dataObject.SetData("CF_WORKFLOW_4", $name)
$dataObject.SetData("WorkflowItemTypeNameFormat", ('{0}{1}' -f $activity, $assemblyFullname))
Write-Host "Load the bitmap {0}" $bitmapPath
Write-Host "$bitmapPath"
$bitmap = new-object System.Drawing.Bitmap $bitmapPath
$toolboxItemInfo = new-object Microsoft.VisualStudio.Shell.Interop.TBXITEMINFO;
$toolboxItemInfo.bstrText = $name
$toolboxItemInfo.hBmp = $bitmap.GetHbitmap()
$toolboxItemInfo.clrTransparent = [System.UInt32][System.Drawing.ColorTranslator]::ToWin32([System.Drawing.Color]::White)
#Create an array with one element
$tbiArray = [Microsoft.VisualStudio.Shell.Interop.TBXITEMINFO[]] ($toolboxItemInfo)
Write-Host "Add the item - this will blow up"
$toolbox.AddItem($dataObject, $tbiArray, $category)
# Exception calling "AddItem" with "3" argument(s): "Exception calling "InvokeMethod" with "3" argument(s): "Object must implement IConvertible.""
# At C:\users\rojacobs\documents\visual studio 2010\Projects\WorkflowConsoleApplication24\packages\Microsoft.Activities.1.8.4.630\tools\install.ps1:53 char:21
# + $toolbox.AddItem <<<< ($dataObject, $tbiArray, $category)
# + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
# + FullyQualifiedErrorId : ScriptMethodRuntimeException
}
Ron, I believe the issue may be surrounding the category. According to the documentation I looked at the category needs to be the localized name (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivstoolbox.additem.aspx) which you can recover using GetIDOfTab (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivstoolbox3.getidoftab.aspx).
Let me know if this helps.