Delete a wiki page with powershell - powershell

I need help with my code.
I first tried to create a new wiki page in SharePoint 2013 and that worked perfectly.
Now I'm trying to delete a wiki page and that doesn't work very well.
My code:
Add-Type –Path "C:\Users\Benutzername\AppData\Local\Apps\OfficeDevPnP.PowerShell.V15.Commands\Modules\OfficeDevPnP.PowerShell.V15.Commands\Microsoft.SharePoint.Client.dll"
Add-Type –Path "C:\Users\Benutzername\AppData\Local\Apps\OfficeDevPnP.PowerShell.V15.Commands\Modules\OfficeDevPnP.PowerShell.V15.Commands\Microsoft.SharePoint.Client.Runtime.dll"
Function Delete-WikiPage ([Microsoft.SharePoint.Client.ClientContext]$Context, [string]$WikiLibraryTitle,[string]$PageName)
{
$wikiLibrary = $context.Web.Lists.GetByTitle($wikiLibraryTitle)
$context.Load($wikiLibrary.RootFolder.Files)
$context.ExecuteQuery()
$wikiPage = $wikiLibrary.RootFolder.Files | Where {$_.Name -eq $pageName}
$context.Load($wikiPage)
$context.DeleteObject()
}
$Url = "hhtps://sharepoint.com"
$context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$pageName = "Testlauf.aspx"
Delete-WikiPage -Context $context -WikiLibraryTitle "Testwiki" -PageName $pageName
I got an error message about the DeleteObject() method but I didn't find anything how I can fix that:
Error when calling the method [Microsoft.SharePoint.Client.ClientContext] no method found with the name "DeleteObject".
In C:\Users\Benutzername\Desktop\Projektarbeit_Wiki\PowerShell\Delete_WikiPage.ps1:12 Zeichen:5
+ $context.DeleteObject()
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
I can only work with methods from the Add-Types. Can anyone help me with this?

You use the CSOM in PowerShell. (you load the CSOM DLL ).
So you should search information with SharPoint CSOM.
To answer you question, you use : DeleteObject() on you object : context. This methode doesn't exist on the Context Object. But the methode exist on the File.
Si you should try something like :
$wikiPage = $wikiLibrary.RootFolder.Files | Where {$_.Name -eq $pageName}
$context.Load($wikiPage)
$context.ExecuteQuery() //Get the item, but not sure this is needed
$wikiPage.DeleteObject()
$context.ExecuteQuery()
personal Note :
You should use CAML query to retrieve your WikiPage, not this: $wikiPage = $wikiLibrary.RootFolder.Files | Where {$_.Name -eq $pageName}
With this kind of query you have bad performance, and you can raise exception list threshold

Related

Why is Export-PnPFlows Skipping Flows?

This is my first post, so please pardon formatting errors!
I've been trying to export my tenant's Power Automate flows via Export-PnPFlow. I have a few hundred flows, so doing it by hand isn't really feasible.
The script works well enough for some flows, but is throwing an error for others, but I can't see why.
It does not seem to be caused by if it's enabled/disabled, owned by a certain user, in a certain environment, or in/out of a solution.
The ones that work, work perfectly; the others give the following error:
Export-PnPFlow : {"error":{"code":"ConnectionAuthorizationFailed","message":"The caller object id is '08#####-#####-####-###'. Connection '2#####-#####-####-####' to 'shared_logicflows' cannot be used to activate this flow, either because
this is not a valid connection or because it is not a connection you have access permission for. Either replace the connection with a valid connection you can access or have the connection owner activate the flow, so the connection is shared with you in the context of
this flow."}}
At C:\Users\jutrust\script.ps1:13 char:21
+ ... Export-PnPFlow -Environment $environment -Identity $flow. ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Export-PnPFlow], HttpRequestException
+ FullyQualifiedErrorId : System.Net.Http.HttpRequestException,PnP.PowerShell.Commands.PowerPlatform.PowerAutomate.ExportFlow
My question is, is it possible that these flows are deleted and that's why I get this error? If so, how can I check?
Code below.
Connect-PnPOnline -url https://########.sharepoint.com
$environments = get-pnppowerplatformenvironment
foreach($environment in $environments)
{
$flows = Get-PnPFlow -Environment $environment -AsAdmin
foreach ($flow in $flows)
{
$filename = $flow.Properties.DisplayName.Replace(" ", "")
$timestamp = Get-Date -Format "yyyymmddhhmmss"
$exportPath = "$($filename)_$($timestamp)"
$exportPath = $exportPath.Split([IO.Path]::GetInvalidFileNameChars()) -join '_'
Export-PnPFlow -Environment $environment -Identity $flow.Name | Out-File "C:\Users\jutrust\documents\$exportPath.json"
}
}
Help!
Edit: Updated error code

Add elements to arry in powershell

I want to simply add some numbers to an array and then sort them via powershell, however, the following code seems to be wrong
$myArray = New-Object System.Collections.ArrayList
Foreach ($Name in $VMName) {
$Tokens = $Name.Split(".")
$myArray.Add($Tokens[$Tokens.Count-1])
}
Write-Host($myArray | Sort-Object)
The error is
+ $myArray.Add($Tokens[$Tokens.Count-1])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
How can I fix that?
The variable $Name is something like 101.u18.uab.14 or 103.win10.template or 102.win7.pink.18 and so on. Each $Name has some . symbols and I want to tokenize them and get the last element for each of them. So, in this example, I want to see a sorted 14 18 template.
UPDATE:
The provided methods seems to be incorrect.
1- This method by Steven
$myArray = New-Object System.Collections.ArrayList
Foreach ($Name in $VMName) {
$Tokens = $Name.Split(".")
[Void]$myArray.Add($Tokens[-1])
}
shows this error
Exception calling "Add" with "1" argument(s): "Collection was of a fixed size."
At C:\Users\user\Desktop\get_ip_list.ps1:20 char:5
+ [Void]$myArray.Add($Tokens[-1])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
2- This method by Santiago
$myArray = [Collections.Generic.List[string]]::new()
Foreach ($Name in $VMName) {
[Void]$myArray.Add($Name.Split(".")[-1])
}
Shows the following error
Exception calling "Add" with "1" argument(s): "Collection was of a fixed size."
At C:\Users\user\Desktop\get_ip_list.ps1:19 char:5
+ [Void]$myArray.Add($Name.Split(".")[-1])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
If I have missed your point in the above codes, please let me know.
I think you are missing the first line from the error. However it looks like you are simply trying to add the last elements from the $Tokens array. In that case you don't need to reference the index like that, below should work:
$myArray = New-Object System.Collections.ArrayList
Foreach ($Name in $VMName) {
$Tokens = $Name.Split(".")
[Void]$myArray.Add($Tokens[-1])
}
Notice the addition of [Void] this will stop the .Add() method from returning the index number it just added to.
Also note you can create array list objects using casting like:
$myArray = [Collections.ArrayList]#()
Update to Address Continued Errors:
The only thing I can think of to cause the error "Collection was of a fixed size." is if you've previously type constrained the variable.
Example:
[String[]]$myArray = #()
# Posibly a whole bunch of other things happening maybe in the console or IDE.
$myArray = [Collections.ArrayList]#()
$myArray.Add('something')
Results:
Exception calling "Add" with "1" argument(s): "Collection was of a fixed size."
At line:1 char:1
+ $myArray.Add('something')...
In this case they type of the $myArray will not change to [Collections.ArrayList]. The problem will be transparent up until you try to use the .Add() method that won't work. This is because an array list is easily and therefore silently cast back to a [String[]] or [Object[]].
Note: If you were to run $myArray.IsFixedSize it would return "True".
My guess as to what's happening; at some point while developing your code or perhaps in the larger script, $myArray got type constrained, and stuck in the scope. This can definitely happen especially given the scope overlap in IDE's like PowerShell's ISE, and I think it happens in VSCode as well. If this is part of a larger script look for instances of $myArray to see if it's indeed type constrained and make corrections as needed. Otherwise a simply restarting your session might do the trick.
Honestly, not sure how could you be getting that error unless the array we're looping through is actually something different. Steven's answer should work fine, I'll put this code below just to show that the results we get are the ones you expect:
$col = [Collections.Generic.List[String]]::new()
$vmName = #(
'101.u18.uab.14'
'103.win10.template'
'102.win7.pink.18'
)
ForEach($name in $vmName)
{
$col.Add($name.Split('.')[-1])
}
if you want absolutly use array you can simply do it :
$Array=#()
$VMName | %{
$Value=($_.Split('.'))[-1]
$Array+= $Value
}
$Array| sort
Otherwise you can simply do it :
$VMName | %{($_.Split('.'))[-1]} | sort

Powershell Like operator invokes REST error

I am working on a custom PoweShell module picked up from the internet for our BI application.
My question is rather simple, the code below does not work:
Get-QlikDataConnection -filter "name -like 'Data*'"
And throws an error like:
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At C:\Program Files\WindowsPowerShell\Modules\Qlik-Cli\1.13\functions\core.ps1:32 char:15
+ ... $result = Invoke-RestMethod -Method $method -Uri $path #params -Web ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
However the code below works fine and shows me the correct output:
Get-QlikDataConnection -filter "name eq 'DataPrepAppCache'"
Am I doing something wrong or do some modules not understand a few operators?
After having a look at the source of the module you're using, Qlik-Admin-Utils, I would not use the -filter param, as the input you specify there gets processed by this block within the Invoke-QlikGet cmdlet:
If( $filter ) {
If( $path.contains("?") ) {
$path += "&filter=$filter"
} else {
$path += "?filter=$filter"
}
}
This script appends your filter as a query parameter in the URL, and it doesn't support regular PowerShell formatting, but sends the filter over to qLik's REST API.
If I were writing this, I'd ignore their filtering and do the following:
$Connections = Get-QlikDataConnection
$DataConnection = $Connections | Where name -like "Data*"
This is more likely to just work with less fiddling.
However, if you want to use Qlik's Filter support, I found this so you can read up on the syntax of it here.
It looks like they do offer a filter of their own which might help, it's the Starts With filter, defined as SW, for a syntax of Name sw 'Data'. You might try this and see if it works instead.
Get-QlikDataConnection -filter "name sw 'Data'"

Add folder to zip

I am facing a problem how to add folder to existing ZIP file.
This zip file is created by PowerShell also.
I can only use system classes provided by Powershell 5. I cannot use any of user packages or plugins (7zip included).
Here is my code:
function addFileToArchiveTest ($filePathToAdd, $archivePathToUpdate) {
if ([System.IO.File]::Exists($filePathToAdd) -or (Test-Path $filePathToAdd)) {
$file = [System.IO.Path]::GetFileName($filePathToAdd);
Write-Host $filePathToAdd.Name;
Write-Host $filePathToAdd;
Write-Host $archivePathToUpdate;
$archive = [System.IO.Compression.ZipFile]::Open($archivePathToUpdate, [System.IO.Compression.ZipArchiveMode]::Update);
$compressionLevel = [System.IO.Compression.CompressionLevel]::NoCompression;
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive, $filePathToAdd, $file, "$compressionLevel");
$archive.Dispose();
} else {
Write-Host "[ERROR#function] <AddFileToArchive>: <filePathToAdd> does not exist!";
Write-Host "[ERROR#function] <Variable<filePathToAdd>>: $filePathToAdd";
Write-Host "[ERROR#function] <Variable<archivePathToUpdate>>: $archivePathToUpdate";
}
}
I am thinking about variable $file - there might be a problem, because folder doesn't have an extension.
I run script like this:
PS> addFileToArchiveTest "C:\TestFolder\FolderToArchive" "C:\TestFolder\thereIsAlreadyZipFile.zip"
It returns with error:
Exception calling "CreateEntryFromFile" with "4" argument(s): "Access to the
path 'C:\TestFolder\FolderToArchive' is denied."
At C:\Users\user\Desktop\testfolder.ps1:196 char:13
+ [System.IO.Compression.ZipFileExtensions]::CreateEntryFro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : UnauthorizedAccessException
Noted I also try allow script and I am launching with admin rights.
Perhaps surprisingly, CreateEntryFromFile() is for adding files, not folders. You need to add each file individually:
Get-ChildItem $filePathToAdd | ForEach-Object {
[IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive, $_.FullName, $_.Name, "$compressionLevel")
}
As user #guiwhatsthat answered: PowerShell 5 does support Compress-Archive. It does exactly what you want.
That is working as I want.

Access DLL classes using PowerShell

I'm trying to use PowerShell to control a Bluethooth dongle which has API document and dll released.
There is an MasterEmulator class under namespace "Nordicsemi" available, I tested it with C#, I can new an instance with MasterEmulator constructor like below, all other functions work fine too.
MasterEmulator masterEmulator = new MasterEmulator();
However I try to do the same with PowerShell with below script.
[System.Reflection.Assembly]::LoadFile($fullpath)
$MasterEmulatorInstance = New-Object Nordicsemi.MasterEmulator
And I get below error:
+ $MasterEmulatorInstance = New-Object Nordicsemi.MasterEmulator
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object],MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
The dll seems to be loaded correctly, I just can't get the constructor to work, I've checked other related posts but New-Object seems to be the only way to access a class from a .Net dll. Not sure what I'm doing wrong here, any hint would be appreciated, thanks.
Update:
Thanks for the replies, I tried more methods of loading assembly like below.
[System.Reflection.Assembly]::LoadFrom($fullpath) | Out-Null
and also without Out-Null cmdlet
[System.Reflection.Assembly]::LoadFrom($fullpath)
the output shows
GAC Version Location
--- ------- --------
False v4.0.30319 D:\Test\MasterEmulator.dll
and still gives me the same error, I also tried below methods.
[reflection.assembly]::loadwithpartialname("MasterEmulator.dll") | Out-Null
Add-Type -Path $fullpath
and still no luck, all of these methods give me the exact same error when I call the constructor.
New-Object : 以 "0" 引數呼叫 ".ctor" 時發生例外狀況: "無法載入檔案或組件 'IronPython, Version=2.7.0.40, Culture=neutral, PublicKeyToken=7f709c5b713576e1' 或其相依性的其中之一。 系統找不到指定的檔案。"
位於 D:\Test\test.ps1:3 字元:27
+ $MasterEmulatorInstance = New-Object Nordicsemi.MasterEmulator
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object],MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
sorry about the Chinese in the error message since the system I'm running is in Chinese, any other ideas?
Try using LoadFrom. Here is how I load MSTranslitTools.DLL which does transliteration.
function load_transliterate(){
$dll = Resolve-Path ".\tools\transliterate\MSTranslitTools.DLL"
[System.Reflection.Assembly]::LoadFrom($dll) | out-null
$specfile = Resolve-Path "Serbian Cyrillic to Latin.tms"
$tspec = [System.NaturalLanguage.Tools.TransliteratorSpecification]::FromSpecificationFile($specfile)
$script:trans = [System.NaturalLanguage.Tools.Transliterator]::FromSpecification($tspec)
Write-Verbose "Transliteration: $($trans.Input) -> $($trans.Output)"
}
Read about the difference here. See also this SO question.