I need help to convert Byte Array to File Stream. I am using following powershell script to download document from web
$wc = New-Object System.Net.WebClient
$bytearr = $wc.downloaddata('URL')
Now, I need to pass this Byte Array to FileSteam
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.ContentStream = ## Need to Pass Byte Array as FileStream ##
Any help?
I am not familiar with the Sharepoint API, but looking at the documentation for the FileCreationInformation class I see there is a Content property of type byte[]. Assuming it serves the same purpose as the ContentStream property, you could do simply...
$FileCreationInfo.Content = $bytearr
If you don't need the data at 'URL' for anything other than populating $FileCreationInfo, consider calling the WebClient.OpenRead method instead to get the data as a Stream in the first place...
$FileCreationInfo.ContentStream = $wc.OpenRead('URI')
As a last resort, and to answer the general question, you can "convert" a byte[] to a Stream by wrapping it in a MemoryStream...
$FileCreationInfo.ContentStream = New-Object -TypeName 'System.IO.MemoryStream' -ArgumentList (,$bytearr)
I have omitted this from my code snippets, but don't forget to Close()/Dispose() any Stream objects you create if the SharePoint client doesn't handle that for you!
Related
I need to create file screen exception in powershell using the FSRM Api, I am using this script to create the cuota but I am having trouble to commit the object.
Because I haven't achieved to meet the requirement to modify AllowedFileGroups property :(
$FSRMObject = New-Object -Com Fsrm.FsrmFilescreenManager
$createFileScreenException = $FSRMObject.CreateFileScreenException("c:\")
$createFileScreenException.AllowedFileGroups("Text Files")
$createFileScreenException.Commit()
This is what I get Listing the Properties and Methods of the Object, in the property definition of AllowedFileGroups I can see that I need to create IFsrmMutableCollection.
Does anyone have an idea of how to create the file screen exception?
AllowedFileGroups is a property, not a method, so I'd expect something like this to work:
$createFileScreenException = $FSRMObject.CreateFileScreenException('c:\')
$createFileScreenException.AllowedFileGroups = 'Text Files'
$createFileScreenException.Commit()
Can't test it, though.
This is how you can create the simplest quota using the FSRM api in powershell, to view more modificable options get the members of the object $quota.
$fsrmQuotaObject = New-Object -Com FSrm.FsrmQuotaManager
$quota = $fsrmQuotaObject.CreateQuota("c:\path")
$quota.ApplyTemplate("Select template")
$quota.Commit()
I have a report in SSRS, which has a parameter in it. For each possibility in the parameter, I need an Excel file. This comes down to 50 Excel files. the only way I know to schedule a report is to go to the reporting services home page, go to my report, click manage, click subscriptions > New subscription and to enter a file name, path, user name, password, schedule, parameter and ultimately press OK.
Is there a quicker way to do this, or is there a way which allows me to create the 50 reports more quickly, like copying a subscription or something like that?
try creating a ssis package and running the report for all values of the parameter. i had seen someone do this in my previous company.
data driven subscriptions are available only in enterprise and developer editions - yours could be standard.
You could also write a script in PowerShell or write an app in C#/VB. Here is an example done in PowerShell. Here is an example done in C#. Using either of these approaches, you could programmatically render the reports as you see fit. You can also create subscriptions this way as well.
PowerShell solution to the OP:
# Create a proxy to the SSRS server and give it the namespace of 'RS' to use for
# instantiating objects later. This class will also be used to create a report
# object.
$reportServerURI = "http://<SERVER>/ReportServer/ReportExecution2005.asmx?WSDL"
$RS = New-WebServiceProxy -Class 'RS' -NameSpace 'RS' -Uri $reportServerURI -UseDefaultCredential
$RS.Url = $reportServerURI
# Set up some variables to hold referenced results from Render
$deviceInfo = "<DeviceInfo><NoHeader>True</NoHeader></DeviceInfo>"
$extension = ""
$mimeType = ""
$encoding = ""
$warnings = $null
$streamIDs = $null
# Next we need to load the report. Since Powershell cannot pass a null string
# (it instead just passes ""), we have to use GetMethod / Invoke to call the
# function that returns the report object. This will load the report in the
# report server object, as well as create a report object that can be used to
# discover information about the report. It's not used in this code, but it can
# be used to discover information about what parameters are needed to execute
# the report.
$reportPath = "/PathTo/Report"
$Report = $RS.GetType().GetMethod("LoadReport").Invoke($RS, #($reportPath, $null))
# Report parameters are handled by creating an array of ParameterValue objects.
# $excelInput: either pass in as a parameter and run 50 times, or reset
# this value and run it each time with the updated excel file
$excelInput = "<ExcelFile>";
$parameters = #()
$parameters += New-Object RS.ParameterValue
$parameters[0].Name = "Excel Input File"
$parameters[0].Value = $excelInput
# Add the parameter array to the service. Note that this returns some
# information about the report that is about to be executed.
$RS.SetExecutionParameters($parameters, "en-us") > $null
# Render the report to a byte array. The first argument is the report format.
# The formats I've tested are: PDF, XML, CSV, WORD (.doc), EXCEL (.xls),
# IMAGE (.tif), MHTML (.mhtml).
$RenderOutput = $RS.Render('PDF',
$deviceInfo,
[ref] $extension,
[ref] $mimeType,
[ref] $encoding,
[ref] $warnings,
[ref] $streamIDs
)
# Convert array bytes to file and write
$OutputFile = $excelInput + ".pdf"
$Stream = New-Object System.IO.FileStream($OutputFile), Create, Write
$Stream.Write($RenderOutput, 0, $RenderOutput.Length)
$Stream.Close()
I have a question, example:
$myxml.SelectSingleNode('//space:XMIS', $space).provider.factories.property.resources[0].name;
I would like to read the properties '.provider.factories.property.resources[0].name' from a text file and assign them to the object.
Can someone help please? I have no idea how to do this dynamically.
Property names can be specified dynamically e.g.:
$date = Get-Date
$prop1 = 'DayOfWeek'
$prop2 = 'value__'
$date.$prop1.$prop2
So read in your dynamic properties from a file and assign each to a variable. This assumes that the depth of properties is the same. That may not work. Another approach is to use XPath for the whole query and then define the XPath in the txt file e.g.:
$ns = #{space = 'http://some-xml-namespace'}
$xpath = Get-Content query.txt -raw
Select-Xml -Xml $myxml -XPath $xpath -Namespace $ns
Content of query.txt
//space:XMIS/space:provider/space:factorties/space:property/space:resources[position()=1]#name
The xpath pattern is just a guess given that I can't see the structure of your xml.
I need to copy a collection of 10 items into an array so I can index into it. So I need to use the CopyTo method and specify a destination array large enough to accommodate the collection.
So before calling CopyTo I need to dim an empty array of a specific size. I can't seem to find the correct PowerShell syntax for doing this.
This didn't work for me:
$snapshot = New-Object System.Array 10;
New-Object : Constructor not found. Cannot find an appropriate constructor for type System.Array.
Edit
Have worked around it with:
$snapshot = New-Object System.Collections.ArrayList;
$snapshot.AddRange($slider);
I think this should do the trick:
$snapshot = #()
Edit:
Ok, sorry about that.
Tested this one:
> $snapshot = New-Object object[] 10
> $snapshot.Length
10
I think just creating a new array will accomplish that in Powershell.
# A "collection of ten items"
$collection = #(1,2,3,4,5,6,7,8,9,0)
#This command creates a new array, sizes it, and copies data into the new array
$newCollection = $collection
Powershell creates a new array in this case. No need to specify the size of the array; Powershell sizes it automatically. And if you add an element to the array, Powershell will take care of the tedious initializeNew-copy-deleteOld routine you have to do in lower-level languages.
Note that $newCollection isn't a reference to the same array that $collection references. It's a reference to a whole new array. Modifying $collection won't affect $newCollection, and vice-versa.
In PowerShell, I want to use New-Object to call a single-argument .Net constructor new X509Certificate2(byte[] byteArray). The problem is when I do this with a byte array from powershell, I get
New-Object : Cannot find an overload for "X509Certificate2" and the argument count: "516".
This approach to using new-object should work:
$cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate `
-ArgumentList #(,$bytes)
The trick is that PowerShell is expecting an array of constructor arguments. When there is only one argument and it is an array, it can confuse PowerShell's overload resolution algorithm. The code above helps it out by putting the byte array in an array with just that one element.
Update: in PowerShell >= v5 you can call the constructor directly like so:
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate]::new($bytes)
Surprisingly to me, I tried this and it seems it works:
[byte[]] $certPublicBytes = something
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate] $certPublicBytes
return $cert
I don't yet know by what magic it works, so your explanatory comments are appreciated. :)
(Note: I since found that using square-brackets-type-name as I did above, can also lead to other errors, such as 'Cannot convert value "System.Byte[]" to type "System.Security.Cryptography.X509Certificates.X509Certificate". Error:
"Cannot find the requested object.' The explicit New-Object approach recommended by Keith seems better!)