Powershell Convert html file to pdf using itext.html2pdf - powershell-4.0

How to convert html to pdf file in Powershell using itext.html2pdf?
I just want to take my input.html file and get an output.pdf file
I am using iText 7 pdfHTML vewrsion 2.1.3
Here is a C# code in the itext website, but how to convert it to Powershell?.
static void Main(string[] args)
{
using (FileStream htmlSource = File.Open("input.html", FileMode.Open))
using (FileStream pdfDest = File.Open("output.pdf", FileMode.OpenOrCreate))
{
ConverterProperties converterProperties = new ConverterProperties();
HtmlConverter.ConvertToPdf(htmlSource, pdfDest, converterProperties);
}
}
Thank you in advance for your help.

Make sure to unpack binaries from the following dependencies for .NET environment into the working directory:
https://www.nuget.org/packages/BouncyCastle/1.8.1
https://www.nuget.org/packages/itext7.pdfhtml/
https://www.nuget.org/packages/itext7/
https://www.nuget.org/packages/Common.Logging/
https://www.nuget.org/packages/Common.Logging.Core/
Then, use the following PowerShell code:
Add-Type -Path "D:\temp\BouncyCastle.Crypto.dll"
Add-Type -Path "D:\temp\Common.Logging.Core.dll"
Add-Type -Path "D:\temp\Common.Logging.dll"
Add-Type -Path "D:\temp\itext.io.dll"
Add-Type -Path "D:\temp\itext.kernel.dll"
Add-Type -Path "D:\temp\itext.forms.dll"
Add-Type -Path "D:\temp\itext.layout.dll"
Add-Type -Path "D:\temp\itext.styledxmlparser.dll"
Add-Type -Path "D:\temp\itext.svg.dll"
Add-Type -Path "D:\temp\itext.html2pdf.dll"
$source = [System.IO.FileInfo]::new("D:\temp\input.html")
$dest = [System.IO.FileInfo]::new("D:\temp\output.pdf")
[iText.Html2Pdf.HtmlConverter]::ConvertToPdf($source, $dest)

Related

How do we add DefaultRequestVersion on an HttpClient object in Powershell?

I have been trying a way to add the Http Version as 1.0 in Powershell to my HttpClient Object.
function Post-JSONData
{
Param
(
[Parameter(Mandatory=$True)] [String] $JSONPayload,
[Parameter(Mandatory=$True)] [String] $ObjectClass,
[Parameter(Mandatory=$True)] [String] $APIUrl,
[Parameter(Mandatory=$False)] [String] $ProxyUrl
)
#Try{
If($JSONPayload.StartsWith("[") -eq $false -and $JSONPayload.EndsWith("]") -eq $false)
{ $JSONPayload = "[" + $JSONPayload + "]" }
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
Add-Type -AssemblyName System.Net.Http
$WebHandler = New-Object System.Net.Http.HttpClientHandler
$WebHandler.AllowAutoRedirect = $false;
If($ProxyUrl)
{
$WebProxy = New-Object System.Net.WebProxy($ProxyUrl)
$WebHandler.Proxy = $WebProxy
}
$HttpClient = New-Object System.Net.Http.HttpClient($WebHandler)
**$HttpClient.DefaultRequestVersion = [System.Net.HttpVersion]::Version10**
$HttpClient.DefaultRequestHeaders.Add("Accept","*/*");
$HttpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
$HttpClient.DefaultRequestHeaders.Add("Connection","keep-alive");
$HttpClient.DefaultRequestHeaders.Add("Class",$ObjectClass);
$HttpClient.Timeout = New-Object System.TimeSpan(0, 0, 90);
$HttpJSONPayload = New-Object System.Net.Http.StringContent($JSONPayload.ToString(), [System.Text.Encoding]::UTF8, "application/json")
$HttpJSONPayload.Headers.ContentEncoding.Add("gzip")
$HttpJSONPayload.Headers.ContentEncoding.Add("deflate")
$HttpJSONPayload.Headers.ContentEncoding.Add("br")
$ResponsePayload = $HttpClient.PostAsync([Uri] $APIUrl,$HttpJSONPayload)
I am able to add the DefaultRequestHeader Parameters but I believe there is some issue with the format for DefaultRequestVersion.
I am unable to find documentation online either for the same.
Update: I am using Powershell V4.0 so $HttpClient.DefaultRequestVersion = [System.Net.HttpVersion]::Version10 is giving the following error:
The property 'DefaultRequestVersion' cannot be found on this object. Verify that the property exists and can be set.
The DefaultRequestVersion property is not a list, but a single HttpVersion value.
To default to HTTP 1.0, assign it like this:
$HttpClient.DefaultRequestVersion = [System.Net.HttpVersion]::Version10
Beware that the DefaultRequestVersion property was only introduced in .NET Core 3.0, so the earliest version of PowerShell with this property exposed is PowerShell 7.0.0
For PowerShell 4.0, you can change your code slightly to support overriding the HTTP Version by manually crafting the request and calling SendAsync() directly (instead of PostAsync()):
Take this line:
$ResponsePayload = $HttpClient.PostAsync([Uri] $APIUrl,$HttpJSONPayload)
... and replace it with:
# Manually craft the request message and overwrite the version
$RequestPayload = New-Object System.Net.Http.HttpRequestMessage #([System.Net.Http.HttpMethod]::Post, [uri]$APIUrl)
$RequestPayload.Version = '1.0'
$RequestPayload.Content = $HttpJSONPayload
# Pass the crafted message directly to SendAsync()
$ResponsePayload = $HttpClient.SendAsync($RequestPayload)

Test user exists with Powershell inputbox

I am trying to script a little application that would make possible to copy AD user's security groups and paste them to another one's profile.
I am good with this part but I want to make it a little bit more difficult by implementing some input boxes that would search for the AD user, errors out in case it does not exit in my AD and prompt once again until user has been found.
ipmo activedirectory
Add-type -assemblyName Microsoft.VisualBasic
Add-Type -AssemblyName System.Windows.Forms
$userref = [Microsoft.VisualBasic.Interaction]::Inputbox("Enter username
", "Prime User")
$usertar = [Microsoft.VisualBasic.Interaction]::Inputbox("Enter username",
"Target")
$userref, $usertar | foreach {
if ([bool](Get-ADUser -Filter {samaccountname -eq $_}) -ne $true) {
[System.Windows.Forms.MessageBox]::Show("This user does not exist!")
}
else {Write-Host "User Ok"}
}
Since you need to validate the existance of two AD users before the rest of your code can run, you are basically asking the same thing twice using inputboxes.
In that case I would suggest adding a small custom function to do that.
Something like this perhaps:
Import-Module ActiveDirectory
Add-type -AssemblyName Microsoft.VisualBasic
Add-Type -AssemblyName System.Windows.Forms
function Get-UserFromInputbox ([string]$Title) {
do {
$account = [Microsoft.VisualBasic.Interaction]::Inputbox("Enter user accountname", $Title)
# On Cancel the InputBox function simply returns an empty string.
# in that case, just return $null so the calling code can handle it
if ([string]::IsNullOrEmpty($account)) { return $null }
# Check if the user can be found
$user = Get-ADUser -Filter "SamAccountName -eq '$account'" –Properties MemberOf -ErrorAction SilentlyContinue
if (!$user) {
# If not found, show the same InputBox again until a valid
# accountname was given or the dialog is cancelled.
[System.Windows.Forms.MessageBox]::Show("User '$account' does not exist!")
}
}
while (!$user)
return $user
}
# Get the AD User object for the source user
$userref = Get-UserFromInputbox -Title "Source User"
if (!$userref) { exit }
# Ditto for the target user
$usertar = Get-UserFromInputbox -Title "Target User"
if (!$usertar) { exit }
# From here on you should have two valid AD user objects with the default properties `DistinguishedName, Enabled,
# GivenName, Name, ObjectClass, ObjectGUID, SamAccountName, SID, Surname, UserPrincipalName`.
# In the function we extended that to also have the `MemberOf` property.
Hope this helps

Add PS Profile to a new local user

I want to create a Powershell profile for a new local user. This new local user is just a copy of Administrator account.
My function function works when profile has been initialized. But it don't work when the Windows profile is not created yet (user still not logged in since the creation of account).
Here is my try:
function add-PSProfile
{
[CmdletBinding()]
Param
(
[Parameter( Mandatory=$true )]
$Login,
[Parameter( Mandatory=$true )]
[ValidateScript({Test-Path $_})]
$RemoteProfilePath
)
# Get default profiles directory
$ProfilesDirectory = ( Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' -ErrorAction Stop ).ProfilesDirectory
$ProfilePath = Join-Path $ProfilesDirectory $Login
$PSProfilePath = Join-Path $ProfilePath 'Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1'
if( -not ( Test-Path $PSProfilePath ) )
{
New-Item -ItemType File -Path $PSProfilePath -Force
}
Copy-Item $RemoteProfilePath $PSProfilePath
}
Do you have any suggestion?
Thanks for your help :)

powershell windows form browes dialogue

Im trying to create a windows form that has a button when clicked will display a folder/file browes window, then the user selects the file/folder and clicks OK and i can then use the selected path as a string for another script.
the problem is that when i run it through PowerGUI (powershell scripting app) it works fine, but when i run through windows powershell it hangs when loading the browse dialog, anyone seen this before or see what ive done wrong or got an alternative, any help would be appreciated.
cls
$button = $browse = $form = 0
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$browse = new-object system.windows.Forms.FolderBrowserDialog
$browse.RootFolder = [System.Environment+SpecialFolder]'MyComputer'
$browse.ShowNewFolderButton = $false
$browse.selectedPath = "C:\"
$browse.Description = "Choose a directory"
$button1 = New-Object system.Windows.Forms.Button
$button1.Text = "Choose Directory"
$button1.Add_Click({$browse.ShowDialog()})
$button1.left = 20
$button1.top = 20
$form = New-Object system.windows.forms.Form
$form.controls.add($button1)
$form.ShowDialog()
$form.Dispose()
$browse.SelectedPath
I was having a similar problem when running my script through PowerShellPlus (anther powershell editor). Luckily I found this post that shows how to prompt for a folder without using the FolderBrowserDialog. Here's the code that I'm using in a set of powershell functions I've written for prompting the user for many different kinds of input via a GUI.
# Show an Open Folder Dialog and return the directory selected by the user.
function Read-FolderBrowserDialog([string]$Message, [string]$InitialDirectory)
{
$app = New-Object -ComObject Shell.Application
$folder = $app.BrowseForFolder(0, $Message, 0, $InitialDirectory)
if ($folder) { return $folder.Self.Path } else { return '' }
}
Your code works when I try it. However I have noticed that sometimes(especially the 2nd time in a session) I use a browsewindow, it is hidden behind the PowerShell console and it seems like it's stuck. So can you try moving your powershell console to the side when it "hangs"?
Also, as a suggestion: if you're only using the form to select a folder location, I would skip it. You won't recieve the browser value until you close the form anyways, so try something like this instead:
function Get-BrowseLocation
{
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
[System.Windows.Forms.Application]::EnableVisualStyles()
$browse = New-Object System.Windows.Forms.FolderBrowserDialog
$browse.RootFolder = [System.Environment+SpecialFolder]'MyComputer'
$browse.ShowNewFolderButton = $false
$browse.Description = "Choose a directory"
$loop = $true
while($loop)
{
if ($browse.ShowDialog() -eq "OK")
{
$loop = $false
} else
{
$res = [System.Windows.Forms.MessageBox]::Show("You clicked Cancel. Try again or exit script?", "Choose a directory", [System.Windows.Forms.MessageBoxButtons]::RetryCancel)
if($res -eq "Cancel")
{
#End script
return
}
}
}
$browse.SelectedPath
$browse.Dispose()
}
PS > Get-BrowseLocation
D:\
If you make the following changes to the function provided by Frode. F, the dialog will always come to the top.
$topform = New-Object System.Windows.Forms.Form
$topform.Topmost = $true
$topform.MinimizeBox = $true
$loop = $true
while($loop)
{
if ($browse.ShowDialog($topform) -eq "OK")
I think you're experiencing the issue I've faced, which is addressed in this question
The answer suggests setting .ShowHelp to $true, like this:
$openFileDialog = New-Object System.Windows.Forms.openFileDialog
$openFileDialog.ShowHelp = $true
$openFileDialog.ShowDialog() | Out-Null

Powershell remoting ApplicationArguments not working

I'm trying to pass some arguments into a new Powershell remoting session using the PSSessionOption's ApplicationArguments property. Unfortunately, the arguments don't seem to show up.
Here's the code:
$client = "Bubba"
$options = New-PSSessionOption -ApplicationArguments #{ Client = $client }
Enter-PSSession -ComputerName "Server" -SessionOption $options
$clientName = $PSSenderInfo.ApplicationArguments.Client
$dir = New-Item "c:\temp\$clientName" -type directory
Exit-PSSession
This results in an error: "NewNotImplementedException at offset 101 in file:line:column..."
Am I doing something wrong?
Apparently Enter-PSSession and Exit-PSSession don't work within a script! They're for interactive command-line use only. This explains the problem.

Resources