Current directory apparently not current directory - powershell

Running this code in ISE works.
Push-Location -Path $(Split-Path -Parent $myInvocation.MyCommand.Path)
Get-Location
$file = '.\ex.txt'
$reader = New-Object System.IO.StreamReader($file)
Running the same code in Console fails. What am I missing?
PS H:\src\powershell> .\ccount.ps1
Path
----
H:\src\powershell
New-Object : Exception calling ".ctor" with "1" argument(s): "Could not find file
'C:\src\powershell\ex.txt'."
At H:\src\powershell\ccount.ps1:9 char:11
+ $reader = New-Object System.IO.StreamReader($file)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands
.NewObjectCommand
How this is different from the suggested duplicate
The other question/answer does give an explanation for why PowerShell fails in this case. However, it does not give any hint as to why this works in ISE. This seems to be a significant difference between the Console and ISE host.
I am running PSVersion 5.0.10586.117 on Windows 7 Enterprise SP1.

Push-Location -Path $(Split-Path -Parent $myInvocation.MyCommand.Path)
$myInvocation.MyCommand.Path
Get-Location
$file = Resolve-Path '.\ex.txt'
$reader = New-Object System.IO.StreamReader($file)

Just use:
Push-Location $PSScriptRoot
It will work in both cases as long as you're using a recent PowerShell version (v3+).

The answer appears to be that Push-Location does not change [Environment]::CurrentDirectory in the console host. It does change it in ISE.
PS 09:02 \\SRV1\SH1\home\pwatson2 H:\
>Push-Location H:\src\t
PS 09:02 \\SRV1\SH1\home\pwatson2 H:\src\t
>Get-Location
Path
----
H:\src\t
PS 09:02 \\SRV1\SH1\home\pwatson2 H:\src\t
>Write-Host ([Environment]::CurrentDirectory)
C:\Windows\System32\WindowsPowerShell\v1.0

Related

Create Shortcut using PowerShell Script

I am trying to create a shortcut on desktop using a Powershell Script. However, I got an error code when trying to run the code below.
$new_object = New-Object -ComObject WScript.Shell
$destination = $new_object.SpecialFolders.Item("AllUsersDesktop")
$source_path = Join-Path -Path $destination -ChildPath "\\Test Intranet.url"
$source = $new_object.CreateShortcut($source_path)
$source.TargetPath = "https://sharepoint.com/"
$source.IconLocation="C:\Users\Public\Pictures\ShortcutIcon.ico"
$source.Save()
Any help will be appreciated.
Thanks.
You didn't show this, but the error message you received is probably this one:
Exception setting "IconLocation": "The property 'IconLocation' cannot be found on this object. Verify that the property exists and can be set."
At line:8 char:1
+ $source.IconLocation="C:\Users\Public\Pictures\ShortcutIcon.ico"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
That is because an Internet shortcut has different properties than a 'normal' (.lnk) shortcut to a file of folder.
Another thing is that you have prefixed the shortcut filename with a double backslash and by doing so, you will get a wrong path: C:\Users\Public\Desktop\\Test Intranet.url
In below code, I have changed some of the variable names to be more self-descripting (at least, I like to think so..)
$shell = New-Object -ComObject WScript.Shell
$destination = $shell.SpecialFolders.Item("AllUsersDesktop")
$shortcutPath = Join-Path -Path $destination -ChildPath 'Test Intranet.url'
# create the shortcut
$shortcut = $shell.CreateShortcut($shortcutPath)
# for a .url shortcut only set the TargetPath
$shortcut.TargetPath = 'https://sharepoint.com/'
$shortcut.Save()
# next update the shortcut with a path to the icon file and the index of that icon
# you can do that because a .url file is just a text file in INI format
Add-Content -Path $shortcutPath -Value "IconFile=C:\Users\Public\Pictures\ShortcutIcon.ico"
Add-Content -Path $shortcutPath -Value "IconIndex=0"
# clean up the COM objects
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shortcut) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
When opened in notepad, your shortcut file looks like this:
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://sharepoint.com/
IconFile=C:\Users\Public\Pictures\ShortcutIcon.ico
IconIndex=0

There is an exception occuring during a web client request in powershell. How to Fix it?

I am using Windows 7. It has powershell Version 2 installed in it. But the version has some bug with split path. So I went with the System.IO.Path for a powershell downloading and executing script. But it is still showing error.
This is the error what I am getting :
+ #('https://cdn.bringatrailer.com/wp-content/uploads/2018/01/GTX-Low-Res-4-940
x627.jpg','https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/2019_Ford_
Mustang_GT_5.0_facelift.jpg/1200px-2019_Ford_Mustang_GT_5.0_facelift.jpg') |for
each{$fileName = $env:TEMP + ([System.IO.Path]::GetFileName($Path) );(New-Objec
t System.Net.WebClient).DownloadFile <<<< ($_,$fileName);Invoke-Item $fileName}
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Exception calling "DownloadFile" with "2" argument(s): "An exception occurred d
uring a WebClient request."
At line:1 char:351
+ #('https://cdn.bringatrailer.com/wp-content/uploads/2018/01/GTX-Low-Res-4-940
x627.jpg','https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/2019_Ford_
Mustang_GT_5.0_facelift.jpg/1200px-2019_Ford_Mustang_GT_5.0_facelift.jpg') |for
each{$fileName = $env:TEMP + ([System.IO.Path]::GetFileName($Path) );(New-Objec
t System.Net.WebClient).DownloadFile <<<< ($_,$fileName);Invoke-Item $fileName}
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Here is my code that i tried to run :
#echo off
powershell "#('https://cdn.bringatrailer.com/wp-content/uploads/2018/01/GTX-Low-Res-4-940x627.jpg','https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/2019_Ford_Mustang_GT_5.0_facelift.jpg/1200px-2019_Ford_Mustang_GT_5.0_facelift.jpg') |foreach{$fileName = $env:TEMP + ([System.IO.Path]::GetFileName($Path) );(New-Object System.Net.WebClient).DownloadFile($_,$fileName);Invoke-Item $fileName}"
PowerShell 2 is depreciated and no longer receiving any updates and has serious risk issues, compared to the current state of the industry and what the newer versions provide for control.
Win7 can use PowerShell v5x. I strongly encourage you to update and use the web cmdlets for this effort and take advantage of the advances in the newer versions.
Now on to you problem. Your have syntax issues, here, even the way you are using PowerShell v2.
#echo off --- is a cmd.exe .bat/.cmd thing, not PowerShell.
If you open this in the ISE or VSCode, you see it is show as an error. So, it's not needed.
For what you are after, take a look at this article:
3 ways to download files with PowerShell
# 1. Invoke-WebRequest
$url = "http://mirror.internode.on.net/pub/test/10meg.test"
$output = "$PSScriptRoot\10meg.test"
$start_time = Get-Date
Invoke-WebRequest -Uri $url -OutFile $output
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
# 2. System.Net.WebClient
$url = "http://mirror.internode.on.net/pub/test/10meg.test"
$output = "$PSScriptRoot\10meg.test"
$start_time = Get-Date
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, $output)
#Or
(New-Object System.Net.WebClient).DownloadFile($url, $output)
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
# 3. Start-BitsTransfer
$url = "http://mirror.internode.on.net/pub/test/10meg.test"
$output = "$PSScriptRoot\10meg.test"
$start_time = Get-Date
Import-Module BitsTransfer
Start-BitsTransfer -Source $url -Destination $output
#Or
Start-BitsTransfer -Source $url -Destination $output -Asynchronous
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
This would be my approach for your use case:
# DownloadPic.ps1
'https://cdn.bringatrailer.com/wp-content/uploads/2018/01/GTX-Low-Res-4-940x627.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/2019_Ford_Mustang_GT_5.0_facelift.jpg/1200px-2019_Ford_Mustang_GT_5.0_facelift.jpg' |
foreach{
$webclient = New-Object System.Net.WebClient
$filename = [System.IO.Path]::GetFileName($PSItem)
$file = "E:\Temp\$filename"
$webclient.DownloadFile($url,$file)
}
Yet, if you are trying to do the traditional double-click to run a file, which does not work with PowerShell natively, so, you are using a batch file for the double-click effort, then I get that.
You'd save the above as a .ps1 file, and in your batch file just call it, something like this.
DownloadPic.bat
::rem batch file calling powershell to download pics.
#echo off
Powershell -noprofile -File "%~E:\temp\DownloadPic.ps1"
See this Q&A
... and point of note. I just wrote this up quickly and tested and it downloaded the pics as expected.
Yet, you can just start a PowerShell prompt and run the script directly.

MyInvocation.MyCommand.Path in ISE vs regular PS

I have an old script that invokes itself with some extra params in a certain situation. This works if run through a regular powershell window
$spath = $script:MyInvocation.MyCommand.Path
$FilePathWithQuotes = '"{0}"' -f $spath
powershell -file $FilePathWithQuotes -NestedCall #ExtraArgs
but if it's run through the ISE I get this error.
powershell : Add-Type : Cannot bind parameter 'Path' to the target.
Exception setting "Path": "Cannot find path At D:\Deploy\File
Deploy.ps1:39 char:5
+ powershell -file $FilePathWithQuotes -NestedCall #ExtraArgs
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Add-Type : Cann...nnot find path :String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
I added the second line to make sure the spaces weren't the issue but it still fails in the ISE.
Thoughts? Im on ps 5.1
Yeah, check for $PSISE, and use that if possible.
$spath = If($PSISE){$psISE.CurrentFile.FullPath}else{$script:MyInvocation.MyCommand.Path}
$FilePathWithQuotes = '"{0}"' -f $spath
powershell -file $FilePathWithQuotes -NestedCall #ExtraArgs

Azure PowerShell - Publish-AzureVMDscConfiguration : throws object not set error

I am writing an automation script for Infrastructure creation in Azure which contains the following code:
Azure-LoginAndPickSubscription -azureSubscriptionId $CONFIG_AZURE["SUBSCRIPTIONID"] `
-azureUsername $CONFIG_AZURE["USERNAME"] `
-azureEncryptedPassword $CONFIG_AZURE["PASSWORD"] `
-passwordKeyFilePath "$SCRIPT_DIRECTORY\private.key"
$solutionRoot = Split-Path -Path $SCRIPT_DIRECTORY -Parent
$storContext = (New-AzureStorageContext -StorageAccountName mystorename -StorageAccountKey "mystoragekey")
Publish-AzureVMDscConfiguration "$SCRIPT_DIRECTORY\NewDSC\InitialConfig.ps1" -ContainerName "windows-powershell-dsc" -Force -StorageContext $storContext
The last line (Publish-AzureVMDscConfiguration) throws an error:
Publish-AzureVMDscConfiguration : Object reference not set to an
instance of an object. At
C:\temp\Base.Deploy\ARM.Create.ps1:38 char:5
+ Publish-AzureVMDscConfiguration "$SCRIPT_DIRECTORY\NewDSC\Initia ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Publish-AzureVMDscConfiguration], NullReferenceException
+ FullyQualifiedErrorId : System.NullReferenceException,Microsoft.WindowsAzure.Commands.ServiceManagement.IaaS.Extensions.DSC.PublishAzureVMDscConfigurationCommand
I have checked the script (InitialConfig.ps1) exists, and the $storContext object is populated. Any ideas what may be causing this?
#Carl,
From your PowerShell code and error message, it seems that you used the ARM mode in your PowerShell. However, your code should use the ASM mode. I recommedn you can use Switch-AzureMode to switch your powershell mode and then run your code again. Please refer to this blog to check their difference (https://blogs.msdn.microsoft.com/powershell/2015/07/20/introducing-azure-resource-manager-cmdlets-for-azure-powershell-dsc-extension/ ). Like this
PS C:\> Switch-AzureMode -Name AzureResourceManager
PS C:\>Switch-AzureMode -Name AzureServiceManagement
Any results, please let me know.

powershell doesn't install AzurePowerShell

I found script on internet, which install WindowsAzurePowerShell, but it doesn't work:
[reflection.assembly]::LoadWithPartialName("Microsoft.Web.PlatformInstaller") | Out-Null
$ProductManager = New-Object Microsoft.Web.PlatformInstaller.ProductManager
$ProductManager.Load()
$product = $ProductManager.Products | Where { $_.ProductId -eq "WindowsAzurePowerShell" }
$InstallManager = New-Object Microsoft.Web.PlatformInstaller.InstallManager
$Language = $ProductManager.GetLanguage("en")
$installertouse = $product.GetInstaller($Language)
$installer = New-Object 'System.Collections.Generic.List[Microsoft.Web.PlatformInstaller.Installer]'
$installer.Add($installertouse)
$InstallManager.Load($installer)
$failureReason=$null
foreach ($installerContext in $InstallManager.InstallerContexts) {
$InstallManager.DownloadInstallerFile($installerContext, [ref]$failureReason)
}
$InstallManager.StartInstallation()
I see exception:
Exception calling "DownloadInstallerFile" with "2" argument(s): "The InstallerContext passed to this method requires a non-Null InstallerFile."
At C:\Users\test.ps1:18 char:5
+ $InstallManager.DownloadInstallerFile($installerContext, [ref]$failureReason ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
So. How it's fixed?
This example I have put together below doesn't go about installing that package the way you where attempting but instead downloads the WebPi CLI, extracts the zip and runs it in an elevated prompt then returns an exit code. I think this will get the job done and can be reproduced on all boxes that may not have the WebPI installed as you can place the file on a share and run this across many computers.
$SourcePath = "http://www.iis.net/community/files/webpi/webpicmd_x86.zip"
$DestinationPath = "c:\Temp\webpicmd_x86.zip"
$ExtractionPath = "c:\Temp\WebPICmd"
$CWebPiCmdLineTool = "$ExtractionPath\WebpiCmdLine.exe"
Import-Module BitsTransfer
Start-BitsTransfer -Source $SourcePath -Destination $DestinationPath
New-Item -Path C:\Temp -Name WebPICmd -ItemType directory | Out-Null
$shell = new-object -com shell.application
$zip = $shell.NameSpace($DestinationPath)
foreach($item in $zip.items())
{
$shell.Namespace($ExtractionPath).copyhere($item)
}
$InstallWebPiPackages = Start-Process -FilePath $CWebPiCmdLineTool -ArgumentList "/Products:WindowsAzurePowerShell" -Verb "RunAs" -Wait -PassThru
$InstallWebPiPackages.ExitCode