We're trying to use Jenkins to convert a set of "Working Documents" into "Release Documents" when it builds out project. This involved taking the .docx files and saving them as .pdf files, which we accomplish with the following Powershell script:
$documents_path = "E:\Documentation\Working Documents\"
$word_app = New-Object -ComObject Word.Application
echo $word_app
# This filter will find .doc as well as .docx documents
$files = Get-ChildItem -Path $documents_path -Filter *.doc?
ForEach ($file in $files) {
echo "Converting Document to PDF: $($file.FullName)"
$document = $word_app.Documents.Open($file.FullName)
$pdf_filename = "$($file.DirectoryName)\..\Release Documents\$($file.BaseName).pdf"
$document.SaveAs([ref] $pdf_filename, [ref] 17)
$document.Close()
}
$word_app.Quit()
Now, that script works 100% the way we expect when I log in to the Jenkins PC and run it myself in Powershell. However, when Jenkins tries running it we get You cannot call a method on a null-valued expression at $document.SaveAs and $document.Close.
I assume this is because the user Jenkins runs as, SYSTEM does not have permission to access the .docx files, or can't find the Word installation, or something of that nature, but I can't think of how I should try to debug it further than this. Any tips are very much appreciated!
I had the same problem and found a simple workaround.
Create an empty directory "Desktop" in
C:\Windows\SysWOW64\config\systemprofile\
Related
New to PowerShell; working through the Windows PowerShell Basics course on edX. But I like to have a project to help me learn. Project: take a folder full of 2 page PDFs and split them each into 2 files, one for each page.
I found iTextSharp but I just cannot figure it out and it is driving me mad. I admit, I know nothing about .NET and next to nothing about PowerShell, so that is likely the main problem. I'm hoping someone can help me out with the basics of iTextSharp in PowerShell.
Embarrassed to post the code I have so far, but here it is:
Add-Type -Path itextsharp.dll
$Files = Get-ChildItem -Filter *.PDF
if (-not (Test-Path .\page1)) {New-Item -Type Directory -Path .\page1}
foreach($File in $Files) {
$EntireDoc = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList $File
$Page1 = $EntireDoc.GetPageContent(1)
$Page2 = $EntireDoc.GetPageContent(2)
}
Even if that did work, I'm not sure how to save the newly created PDF files.
I am having difficulty figuring this one out. I am trying to download a file using powershell (via batch, so it must be on one line), but preserve the original creation date/time and modified date/time. The code I am currently using writes the date/time that the file was downloaded as the created & modified date.
(new-object System.Net.WebClient).DownloadFile('https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3','%USERPROFILE%\Downloads\file_example_MP3_700KB.mp3')
I've been able to accomplish this with a download manager, but I would like to be able to get this done via powershell so I can schedule the download on system start-up. I've searched for code to suit my needs, but can't find any that fit the criteria.
Ive found these, but i'm not sure how to incorporate them:
.TimeLastModified .LastModified .LastWriteTime .CreationTime
any help would be greatly appreciated.
Just use BITS, it copies remote file time by default and will even draw a nice progress bar when running interactively.
Start-BitsTransfer -Source 'https://google.com/favicon.ico' -Destination 'c:\Temp\2.ico'
My previous answer for history:
$request = [System.Net.WebRequest]::Create('https://google.com/favicon.ico')
$response = $request.GetResponse()
$stream = $response.GetResponseStream()
$file = New-Object System.IO.FileInfo 'c:\Temp\1.ico'
$fileStream = $file.OpenWrite()
$stream.CopyTo($fileStream)
$stream.Close()
$fileStream.Close()
$file.CreationTime = $file.LastWriteTime = $response.LastModified
If the server does not report file time, it will be set to current time.
If you need an one-liner, combine the lines with ;.
In PowerShell 3+ you can use a simpler alternative:
$fileName = 'c:\Temp\1.ico'
$response = Invoke-WebRequest 'https://google.com/favicon.ico' -OutFile $fileName -PassThru
$file = Get-ChildItem $fileName
$file.CreationTime = $file.LastWriteTime = $response.BaseResponse.LastModified
I am trying to use PowerShell to Sync Payroll files stored on SFTP to SharePoint. I have most of the code written, the only thing I can't figure out is if there is a way to avoid temporarily downloading the file to the disk. Given the sensitivity of these files I would rather store the files as a variable not unlike how get-content works so no one on the Jenkins slave would be able to see its content or undelete temp files.
Here is my working code that does download the file:
$session = New-Object WinSCP.Session
$session.Open($sessionOptions)
$file = $session.ListDirectory("/") | select -ExpandProperty files | ? {$_.FileType -ne "D"} | select -First 1
$session.GetFiles($file, "c:\temp\$($file.name)", $False, $transferOptions)
$session.Close()
Is there something I can use in replacement of the second parameter of WinSCP.Session.GetFiles [C:\temp\$($file.name)] that would allow me to drop the file directly into memory so I can turn around and dump the to SharePoint?
If you were wondering how I would then get it into sharepoint I have used this with get-content without issue:
$fileToUpload = get-content c:\temp\test.csv -Encoding Byte
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.Content = $fileToUpload
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.Url = "test.csv"
$Upload = $Folder.Files.Add($FileCreationInfo)
$Ctx.Load($Upload)
$Ctx.ExecuteQuery()
WinSCP simply doesn't do it. I had been hoping for a downstream object to take the replcement of a file path but that does not seem to be possible. However I did figure this out. Moving to the posh-ssh module I was able to use the Get-SFTPContent command which allows me to read in the file to memory.
install-module posh-ssh
import-module posh-ssh
$Session = New-SFTPSession -ComputerName $SFTPHostName -Credential $SFTPcredential
Get-SFTPContent -SessionId $session.SessionId -Path $file.FullName -Encoding unicode -ContentType byte
Streaming a context of a remote file is supported since WinSCP 5.18 beta using the Session.GetFile method.
$stream = $session.GetFile($file)
I have a a lot of files that are windows themepacks that I want to open up. I don't want to just go down the list and double-click each one. So I sent the get-childitem to the variable $item and then loop through it, next I want to open each file. Just using the name and ./windows7.theme works however code doesn't. I have tried the different options below and they don't work, please help. Also, let me know of any other methods to open files through PowerShell
foreach($item in $i){$a=$item.name;./$a}
foreach($item in $i){$a=$item.name;./($a)}
foreach($item in $i){./($item.name)}
Use:
invoke-item $a
The Invoke-Item cmdlet performs the default action on the specified item. For example, it runs an executable file or opens a document
file in the application associated with the document file type.
more info:
get-help invoke-item -full
Or you can try this
$baselocation = (Get-Location).Path + "\Desktop\"
$fileExtension = ".txt"
foreach($itm in $var)
{
&($baselocation+ $itm.name + $fileExtension)
}
My file which just lists the name of the other files are in C:\users\user1\Desktop
Source: Invocation Operator
Trying to extract just .sql files from zip powershell
Referring to the above link, a powershell script was made to extract only .sql files.
Is there a way to reverse this, so it extracts everything from the Zip file apart from .Inf files.
Any help will be greatly appreciated, as my powershell skills are next to none.
$shell = New-Object -COM 'Shell.Application'
$zipfile = 'C:\Powershell\From here\1-5'
$destination = 'C:\Powershell\To Here'
$zip = $shell.NameSpace($zipfile)
$zip.Items() | ? { $_.Path -notlike '*.inf' } | % {
$shell.NameSpace($destination).CopyHere($_)
}
It would be helpful if you posted your code but in general you could use an operator like -notlike or -notmatch to achieve what you want to do.