extracting zip files with powershell - powershell

I am trying to extract a zip file to then be downloaded by remote people. Once extracted I will have a script that installs the package but I need to use a compressed folder and the remote users don't have 7zip or anything like it.
I have this but I keep getting an error -
$shell = new-object -com shell.application
$zip = $shell.NameSpace(“C:\name.zip”)
foreach($item in $zip.items())
{
$shell.Namespace(“C:\temp\name”).copyhere($item)
}
The error I am getting is below -
You cannot call a method on a null-valued expression.
At line:5 char:43
+ $shell.Namespace(“C:\name”).copyhere <<<< ($item)
+ CategoryInfo : InvalidOperation: (copyhere:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
There are other issues with the code but this is a work in progress, I will fix the hard coding of values once I can get it to extract.

Does your extract path exist (“C:\temp\name”)? To be clear, both of the items in that path should be directories.
That should be a path that already exists. If it doesn't you get that error.

Related

Unable to convert XML to JSON using [newtonsoft.Json.JsonConvert]::SerializeXmlNode method in powershell

I am trying to convert the content of a xml file to json using powershell.
When I call to the method, the powershell returns the error as below:
Method invocation failed because [Newtonsoft.Json.JsonConvert] does not contain a method named 'SerializeXmlNode'.
At line:1 char:1
+ $jsonText = [newtonsoft.Json.JsonConvert]::SerializeXmlNode($xmlDoc)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
I also checked the newtonsoft website below but the SerializeXmlNode method seemed to not have been deprecated:
newtonsoft - SerializeXmlNode
Kindly check my script below:
Import-Module newtonsoft.json
$filename = "E:\Udemy\Complete Guide to XML For Microsoft Developers\Lecture 5\XMLClass_Downloads_2021_03_28\IntroSamples\Flight01.xml"
#[xml]$xmlDoc = [IO.File]::ReadAllText($filename)
[xml]$xmlDoc = Get-Content $filename
Write-Host $xmlDoc.OuterXml
Write-Host "------------------------------------------------------------"
$jsonText = [Newtonsoft.Json.JsonConvert]::SerializeXmlNode($xmlDoc)
How can I convert the xml to json using SerializeXmlNode method or any of its equivalent ?
Kind regards,
Ken
Download the latest Json dll from here and unzip it somewhere after you have right-clicked the zip file, selected 'Properties' and unblocked it.
Suppose you have chosen path 'C:\Program Files\NewtonSoft' to store the unzipped folder, then put this at the top of your script:
$jsonDllPath = 'C:\Program Files\NewtonSoft\Json130r1\Bin\net40\Newtonsoft.Json.dll'
Add-Type -Path $jsonDllPath
$filename = 'E:\Udemy\Complete Guide to XML For Microsoft Developers\Lecture 5\XMLClass_Downloads_2021_03_28\IntroSamples\Flight01.xml'
# load the xml file. This way, you are ensured to get the file encoding correct
$xmlDoc = [System.Xml.XmlDocument]::new()
$xmlDoc.Load($filename)
Write-Host $xmlDoc.OuterXml
Write-Host "------------------------------------------------------------"
# this should now work:
$jsonText = [Newtonsoft.Json.JsonConvert]::SerializeXmlNode($xmlDoc)
Depending on the XML, if it has an xml declaration line or not, you may want to use [Newtonsoft.Json.JsonConvert]::SerializeXmlNode($xmlDoc.DocumentElement)

Use variable for URL in powershell BITS transfer

I have the following in a powershell script:
$src_url = "http://my_server/my_file.zip"
if (!(Test-Path $src_zip))
{
"Downloading $src_url"
Start-BitsTransfer -Source "$src_url" -Destination .\$src_zip
}
The output of which is
Downloading http://my_server/my_file.zip
Start-BitsTransfer : The server name or address could not be resolved
At C:\foo.ps1:18 char:5
+ Start-BitsTransfer -Source "$src_url" -Destination .\$src_zip
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Start-BitsTransfer], Exception
+ FullyQualifiedErrorId : StartBitsTransferCOMException,Microsoft.BackgroundIntelligentTransfer.Management.NewBitsTransferComma
nd
I have tried with, without double and single quotes around the URL. However if I type the URL out directly the name is resolved correctly. What should I do to expand $src_url?
Considering it works with hard-coding URL, the source variable should expand correctly in your syntax.
And from error you pasted, it may due to destination path resolution. Try to use full path in it. Example,
$src_zip = "C:\temp\abc.zip"
Please see if the destination file needs to be removed or you can use force parameter.

How can I use the unmanaged UI Automation API from PowerShell

The UI Automation API for Windows is available from two DLLs.
One is a managed DLL, which is C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\UIAutomationClient.dll.
The other is an unmanaged DLL, which is C:\Windows\System32\UIAutomationCore.dll.
According to this post, the unmanaged API is superior to the managed API in terms of the number of visible elements, so I would like to use the unmanaged API.
I have tried three approaches, but all of them failed.
Would you tell me the correct approach?
Approach #1: New-Object -ComObject
$uia = New-Object -ComObject <ProgID of CUIAutomation>
$root = $uia.GetRootElement()
Failed because New-Object requires ProgID but CUIAutomation does not have ProgID.
Approach #2: Instantiation from CLSID
The CLSID of CUIAutomation is ff48dba4-60ef-4201-aa87-54103eef594e, then,
$type = [Type]::GetTypeFromCLSID("ff48dba4-60ef-4201-aa87-54103eef594e")
$uia = [Activator]::CreateInstance($type)
$root = $uia.GetRootElement()
but failed with the following error message.
I still do not know why.
Method invocation failed because [System.__ComObject] does not contain a method named 'GetRootElement'.
At line:1 char:1
+ $root = $uia.GetRootElement()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Approach #3: Add-Type
Add-Type -Path "C:\Windows\System32\UIAutomationCore.dll"
$uia = New-Object UIAutomationClient.CUIAutomation
$root = $uia.GetRootElement()
Failed because Add-Type expects managed DLLs.
Error message:
Add-Type : Could not load file or assembly 'file:///C:\Windows\System32\UIAutomationCore.dll' or one of its dependencies. The module was expected to contain an assembly manifest. At line:1 char:1
+ Add-Type -Path "C:\Windows\System32\UIAutomationCore.dll"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Add-Type], BadImageFormatException
+ FullyQualifiedErrorId : System.BadImageFormatException,Microsoft.PowerShell.Commands.AddTypeCommand
Edit (2018-06-12)
I tried another approach. (and failed)
Approach #4: Interop DLL
I do not really understand what exactly the Interop DLL is, but this post says the Interop DLL helped OP anyway.
I installed Visual Studio and generated Interop.UIAutomationClient.dll by following the procedures of the post.
Add-Type -Path "Interop.UIAutomationClient.dll"
$uia = New-Object UIAutomationClient.CUIAutomationClass
$root = $uia.GetRootElement()
$children = $root.FindAll([UIAutomationClient.TreeScope]::TreeScope_Children, $uia.CreateTrueCondition())
I succeeded in obtaining $root, but failed at the line of $children with the following error message.
Method invocation failed because [System.__ComObject] does not contain a method named 'FindAll'.
At line:1 char:1
+ $children = $root.FindAll([UIAutomationClient.TreeScope]::TreeScope_C ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
I still do not know why.
What about this?:
Add-Type -AssemblyName 'UIAutomationClient'
$ae = [System.Windows.Automation.AutomationElement]
$cTrue = [System.Windows.Automation.PropertyCondition]::TrueCondition
$root = $ae::RootElement
$winNames = $root.FindAll("Children", $cTrue).current.name
I have not yet resolved the problem, but finally found an alternative, that is C# Interactive.
I will leave this question for PowerShell users, but, if you can use C# Interactive as an alternative of PowerShell, the following section may help you.
Approach #5: C# Interactive
Install Visual Studio.
Generate Interop.UIAutomationClient.dll by following the procedures of this post.
Run the following script on csi.exe.
#r "Interop.UIAutomationClient.dll"
var uia = new UIAutomationClient.CUIAutomation();
var root = uia.GetRootElement();
var children = root.FindAll(UIAutomationClient.TreeScope.TreeScope_Children, uia.CreateTrueCondition());
FYI, C# Interactive works if only the following files exist in the same folder (i.e., you can use C# Interactive anywhere just by bringing the following files from the development environment).
C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe
C:\Program Files (x86)\MSBuild\14.0\Bin\csi.rsp
C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.CSharp.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.CSharp.Scripting.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.Scripting.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.AppContext.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.Collections.Immutable.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.Diagnostics.StackTrace.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.IO.FileSystem.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.Reflection.Metadata.dll
Approach 2 you should get to the interface of
IID_IUIAutomation = "{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}"
CLSID_UIAutomationClient = "{944DE083-8FB8-45CF-BCB7-C477ACB2F897}"
;CoClasses
CLSID_CUIAutomation = "{FF48DBA4-60EF-4201-AA87-54103EEF594E}"
MS Doc states
Remarks
Every UI Automation client application must obtain this interface to a CUIAutomation object in order to gain access to the functionality of UI Automation.
The following example function creates a CUIAutomation object and obtains the
IUIAutomation interface.
IUIAutomation *g_pAutomation;
BOOL InitializeUIAutomation()
{
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IUIAutomation), (void**)&g_pAutomation);
return (SUCCEEDED(hr));
}
I was not able to get it working in PS but maybe this answers helps partly in the right direction (I have it working in AutoIt but that works differently, you can find it with AutoIt IUIAutomation on google)
$objCUI=[System.Runtime.InteropServices.Marshal]::GetTypeFromCLSID("30CBE57D-D9D0-452A-AB13-7AC5AC4825EE")
or
$Type = [Type]::GetTypeFromCLSID('30CBE57D-D9D0-452A-AB13-7AC5AC4825EE')
$objCUI = [System.Activator]::CreateInstance($Type)
both run but when I come to
$rootEl = $objCUI.GetType().InvokeMember(
"GetRootElement",
"InvokeMethod",
$Null,
$objCUI,
#()
)
I get errors

Remove-Item Vs [System.IO.File]::Delete()

I have the following code in an Azure Runbook:
$pathToDownloadedBlob = 'C:\depId-20150904032522\SevenZipSharp.dll'
if ((Test-Path $pathToDownloadedBlob) -eq $true)
{
try
{
Remove-Item -Path $pathToDownloadedBlob
}
catch
{
write-error "Could not delete $pathToDownloadedBlob. - $($error[0])"
exit
}
}
When I use Remove-Item I get this error:
4/7/2015 2:14:14 PM, Error: Remove-Item : The converted JSON string is in bad format.
At DavidTest:45 char:45
+
+ CategoryInfo : InvalidOperation: (System.Unauthor... Boolean force):ErrorRecord) [Remove-Item],
InvalidOperationException
+ FullyQualifiedErrorId : JsonStringInBadFormat,Microsoft.PowerShell.Commands.RemoveItemCommand
When I use [System.IO.File]::Delete($using:path) instead, I get this error:
4/7/2015 2:22:48 PM, Error: Exception calling "Delete" with "1" argument(s): "Access to the path 'C:\Deployment\SevenZipSharp.dll' is denied."
At DavidTest:46 char:46
+
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : UnauthorizedAccessException
I know I don't have permission to delete the file.
However, why is it complaining about a JSON string when I use Remove-Item?
EDIT:
Note this only happens in Azure Automation. However I wasn't truly able to replicate this in Powershell ISE locally because I have permission to files I wish to delete.
UPDATE:I just realised this is only happening for .dll files. If I try to delete a .7z file it works fine.
I would imagine that this is due to the serialization / deserialization of the object being passed between the PowerShell Workflow context, and the InlineScript Workflow Activity, which runs in a separate process by default.
Are you always passing in a [System.String], or are you sometimes passing in a [System.IO.FileInfo] object? If the latter, then you'll probably want to reference the FullName property, rather than passing in the object itself to Remove-Item.
I'm not 100% sure that this is what you're running into, but it's worth discussing.
By the way, as a best practice, always explicitly name your parameters, so other people understand what you're doing. Your call to Remove-Item doesn't include the -Path parameter, by name, because it's positionally at 0. Of course, this isn't a good thing to take for granted when you're asking for help. Better to be verbose.
Hope this helps at least a bit. By the way, is this problem unique to Azure Automation Runbooks, or does it also exist in locally executed PowerShell Workflows?
Edit: This code seems to work just fine for me locally.
workflow test {
$Path = 'C:\dsc\srv01.xml';
InlineScript { Remove-Item -Path $using:Path; };
}
test

Having issue removing a file in powershell

I'm trying to remove a file after checking some thing in that. I'm capturing the whole path into a variable and passing it to Remove-Item command and I'm getting below error:
Remove-Item : An object at the specified path E:\Import\IRIS_Import\working\RP
LS_BAI_20120719092600450-20120719093206.csv does not exist.
At E:\Import\IRIS_Import\FIX_IRIS_49_FILES_kr.ps1:53 char:13
+ Remove-Item <<<< $file
+ CategoryInfo : InvalidArgument: (:) [Remove-Item], PSArgumentEx
ception
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.RemoveIte
mCommand
Not sure why Powershell is complaining about file not being there even I can see the file there physically. Any ideas please?
I faced this exact same issue when I ran an Azure powershell webjob. I followed the answer in another thread in addition's to justinf's answer in this thread and modified my remove-item command as below.
remove-item filesystem::\\uncpath\folder
Your problem is that the file had an - in the file name and powershell does not like this it would seem.
This code worked for me. If it does not work for you post more of your code up and I will take a look.
$test = "c:\test\LS_BAI_20120719092600450-20120719093206.csv"
Remove-Item -LiteralPath $test