Rectangle 27 14

When Resolve-Path fails due to the file not existing, the fully resolved path is accessible from the thrown error object.

You can use a function like the following to fix Resolve-Path and make it work like you expect.

function Force-Resolve-Path {
    <#
    .SYNOPSIS
        Calls Resolve-Path but works for files that don't exist.
    .REMARKS
        From http://devhawk.net/2010/01/21/fixing-powershells-busted-resolve-path-cmdlet/
    #>
    param (
        [string] $FileName
    )

    $FileName = Resolve-Path $FileName -ErrorAction SilentlyContinue `
                                       -ErrorVariable _frperror
    if (-not($FileName)) {
        $FileName = $_frperror[0].TargetObject
    }

    return $FileName
}

Powershell: resolve path that might not exist? - Stack Overflow

powershell
Rectangle 27 14

When Resolve-Path fails due to the file not existing, the fully resolved path is accessible from the thrown error object.

You can use a function like the following to fix Resolve-Path and make it work like you expect.

function Force-Resolve-Path {
    <#
    .SYNOPSIS
        Calls Resolve-Path but works for files that don't exist.
    .REMARKS
        From http://devhawk.net/2010/01/21/fixing-powershells-busted-resolve-path-cmdlet/
    #>
    param (
        [string] $FileName
    )

    $FileName = Resolve-Path $FileName -ErrorAction SilentlyContinue `
                                       -ErrorVariable _frperror
    if (-not($FileName)) {
        $FileName = $_frperror[0].TargetObject
    }

    return $FileName
}

Powershell: resolve path that might not exist? - Stack Overflow

powershell
Rectangle 27 7

I went ahead and looked into the Invoke-WebRequest cmdlet code and found out why it's failing with this particular error.

It's failing on a call to System.Globalization.EncodingTable.GetCodePageFromName. The encoding is passed to that function as a parameter and the encoding is retrieved from the the cmdlet through the Content-Type header. In the case of this server the Content-Type was sent back in the response as Content-Type: application/xml; charset="UTF-8".

The problem with this is that quotes aren't standard for wrapping the value in charset so the cmdlet parses it out as "UTF-8" instead of the valid UTF-8. The cmdlet passes "UTF-8" to the function and the function throws an exception stating that the provided encoding is invalid. This is fine and would make so much more sense if that is what was reported in the final exception but it's not.

The Invalid encoding exception is caught by the Microsoft.PowerShell.Commands.ContentHelper.GetEncodingOrDefault function and in the exception handler it calls GetEncoding again but with a null parameter which results in the final ArgumentNullException for parameter name.

internal static Encoding GetEncodingOrDefault(string characterSet)
{
  string name = string.IsNullOrEmpty(characterSet) ? "ISO-8859-1" : characterSet;
  try
  {
    return Encoding.GetEncoding(name);
  }
  catch (ArgumentException ex)
  {
    return Encoding.GetEncoding((string) null);
  }
}

The call to GetEncoding inside the catch statement triggers the following code inside GetCodePageFromName which is itself called from GetEncoding

if (name==null) { 
    throw new ArgumentNullException("name");
}

PowerShell is handling this properly since technically it is an invalid value but you'd think they would call Trim("\"") just to be safe.

I'm running into this problem with Python 2.7's SimpleHTTPServer.

Thanks for discovering the root cause. I've seen this manifest on a fully patched Windows Server 2012 R2 box with PowerShell (WMF) 5.1 installed. Take the same code over to Windows 10 or Windows Server 2016 and there is no issue. Very disappointing as there doesn't seem to be a solution.

powershell - Why is Invoke-WebRequest and Invoke-RestMethod failing an...

powershell
Rectangle 27 235

If you're going to use the registry you have to recurse in order to get the full version for the 4.x Framework. The earlier answers both return the root number on my system for .NET 3.0 (where the WCF and WPF numbers, which are nested under 3.0, are higher -- I can't explain that), and fail to return anything for 4.0 ...

EDIT: For .Net 4.5 and up, this changed slightly again, so there's now a nice MSDN article here explaining how to convert the Release value to a .Net version number, it's a total train wreck :-(

This looks right to me (note that it outputs separate version numbers for WCF & WPF on 3.0. I don't know what that's about). It also outputs both Client and Full on 4.0 (if you have them both installed):

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Version,Release -EA 0 |
Where { $_.PSChildName -match '^(?!S)\p{L}'} |
Select PSChildName, Version, Release

Based on the MSDN article, you could build a lookup table and return the marketing product version number for releases after 4.5:

$Lookup = ConvertFrom-Csv 'Version|Release
4.5|378389
4.5.1|378675
4.5.1|378758
4.5.2|379893
4.6|393295
4.6|393297
4.6.1|394254
4.6.1|394271
4.6.2|394802
4.6.2|394806
4.7|460798
4.7|460805
4.7.1|461308
4.7.1|461310
' -Delimiter "|"

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
    Get-ItemProperty -name Version,Release -EA 0 |
    Where { $_.PSChildName -match '^(?!S)\p{L}'} |
    Select PSChildName, Version, Release, @{
        name       = "Product"
        expression = {
            $Lookup | ? Release -eq $_.Release | % Version
        }
    }

In fact, since I keep having to update this answer, here's a script to generate the script above from the markdown source for that web page. This will probably break at some point, so I'm keeping the current copy above.

# Get the text from github
$url = "https://raw.githubusercontent.com/dotnet/docs/master/docs/framework/migration-guide/how-to-determine-which-versions-are-installed.md"
$md  = Invoke-WebRequest $url -UseBasicParsing

# Replace the weird text in the tables, and the padding
# Then trim the | off the front and end of lines
$map = $md -split "`n" -replace " installed [^|]+" -replace "\s+\|" -replace "\|$" |

# Then select all the lines that start with ".NET Framework"
# and make sure we don't have duplicates
Select-String "^.NET" | Select -Unique 

# Then remove the .NET Framework
$map = $map -replace ".NET Framework " -join "`n"

# And just output the script
@"
`$Lookup = ConvertFrom-Csv 'Version|Release
$map
' -Delimiter "|"

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
    Get-ItemProperty -name Version,Release -EA 0 |
    Where { `$_.PSChildName -match '^(?!S)\p{L}'} |
    Select PSChildName, Version, Release, @{
        name="Product"
        expression={
            `$Lookup | ? Release -eq `$_.Release | % Version
        }
    }
"@

This is exactly what I am looking for as well, but I am having a hard time wrapping my mind around what exactly this is doing. From what I understand it is going out to the NDP registry and recursively searching through each folder that fits the '^(?!S)\p{L}' regex and getting the Version and Release info. What exactly is that regular expression trying to qualify?

@Johnrad PSChildName is the leaf name of the registry key. \p{L} is the any character in the Unicode category "letter". (?!S) is a negative look around, and ^ is the start of the string. So it has to start with a letter other than S. So if you consider only ASCII, it's the same as $_.PSChildName -cmatch '^[A-RT-Za-z]' (note the -cmatch). So it finds keys where the name starts with a letter other than S. I have no idea why you'd care about non-ASCII if you're filtering out names starting with S... Definitely with you on it being so confusing.

Now I'm more confused about what the heck Get-ItemProperty -name Version,Release -EA 0 is doing. I know -EA 0 is the same as -ErrorAction SilentlyContinue, but what effect would Get-ItemProperty -name Version,Release have when piping all the results to it? It doesn't seem to strip off any variables from the object, as others are used in later commands in the pipeline. Does it run, error out when the Version or Release name is missing from the key, and then pass objects where it succeeded on into the next command in the pipeline?

The Get-ChildItem returns ALL the registry subkeys (the subfolders, if you will). Get-ItemProperty returns the values (specifically: "Version" and "Release") -- we ignore the errors because we don't care about folders that don't have those values. So yes, basically we find EVERY subfolder, and then look for Version or Release (any folders without one or both of those is ignored).

Awesome! I only modified the (?!S) clause to be (?![SW]) to further exclude the "Windows*" entries. This can also be done with (?=[vCF]) since the only keys we really care about are the Version roots and the "Full" and "Client" keys for .NET 4.0+. ;)

PowerShell script to return versions of .NET Framework on a machine? -...

.net powershell version
Rectangle 27 3

I was going crazy trying to make capturing the STDERR stream to a variable work. I finally solved it. There is a quirk in the invoke-expression command that makes the whole 2&>1 redirect fail, but if you omit the 1 it does the right thing.

function runDOScmd($cmd, $cmdargs)
 {
 # record the current ErrorActionPreference
     $ep_restore = $ErrorActionPreference
 # set the ErrorActionPreference  
     $ErrorActionPreference="SilentlyContinue"

 # initialize the output vars
     $errout = $stdout = ""

 # After hours of tweak and run I stumbled on this solution
 $null = iex "& $cmd $cmdargs 2>''"  -ErrorVariable errout -OutVariable stdout
 <#                       these are two apostrophes after the >
     From what I can tell, in order to catch the stderr stream you need to try to redirect it,
     the -ErrorVariable param won't get anything unless you do. It seems that powershell
     intercepts the redirected stream, but it must be redirected first.
 #>
 # restore the ErrorActionPreference
 $ErrorActionPreference=$ep_restore

 # I do this because I am only interested in the message portion
 # $errout is actually a full ErrorRecord object
     $errrpt = ""
     if($errout)
     {
         $errrpt = $errout[0].Exception
     }

 # return a 3 member arraylist with the results.
     $LASTEXITCODE, $stdout, $errrpt
 }

This is the only solution that I managed to get working. Thanks!

PowerShell: Manage errors with Invoke-Expression - Stack Overflow

powershell
Rectangle 27 2

Yes, as other answers have states, it cannot be done with Write-Output. Where PowerShell fails, turn to .NET, there are even a couple of .NET answers here but they are more complex than they need to be.

[Console]::Write("Enabling feature XYZ.......")
Enable-SPFeature...
Write-Output "Done"

It is not purest PowerShell, but it works.

Downvoted because this behaves just like Write-Host, except people will not expect it.

How do I output text without a newline in PowerShell? - Stack Overflow

powershell
Rectangle 27 2

Yes, as other answers have states, it cannot be done with Write-Output. Where PowerShell fails, turn to .NET, there are even a couple of .NET answers here but they are more complex than they need to be.

[Console]::Write("Enabling feature XYZ.......")
Enable-SPFeature...
Write-Output "Done"

It is not purest PowerShell, but it works.

Downvoted because this behaves just like Write-Host, except people will not expect it.

How do I output text without a newline in PowerShell? - Stack Overflow

powershell
Rectangle 27 50

There are certain scenarios in which you can follow the steps suggested in the other answers, verify that Execution Policy is set correctly, and still have your scripts fail. If this happens to you, you are probably on a 64-bit machine with both 32-bit and 64-bit versions of PowerShell, and the failure is happening on the version that doesn't have Execution Policy set. The setting does not apply to both versions, so you have to explicitly set it twice.

Look in your Windows directory for System32 and SysWOW64.

Check the current setting for ExecutionPolicy:

Get-ExecutionPolicy -List

Set the ExecutionPolicy for the level and scope you want, for example:

Set-ExecutionPolicy -Scope LocalMachine Unrestricted

Note that you may need to run PowerShell as administrator depending on the scope you are trying to set the policy for.

This solved it for me (on a 64-bit machine)

This answer actually led me to what was giving me the same Error message. I was running a powershell script with a scheduled task, but rather than use my windows user to run the script, I was using another account (a service account). I had to log in as that account and unrestrict the scripts for that user as well.

c# - .ps1 cannot be loaded because the execution of scripts is disable...

c# asp.net powershell
Rectangle 27 45

There are certain scenarios in which you can follow the steps suggested in the other answers, verify that Execution Policy is set correctly, and still have your scripts fail. If this happens to you, you are probably on a 64-bit machine with both 32-bit and 64-bit versions of PowerShell, and the failure is happening on the version that doesn't have Execution Policy set. The setting does not apply to both versions, so you have to explicitly set it twice.

Look in your Windows directory for System32 and SysWOW64.

Check the current setting for ExecutionPolicy:

Get-ExecutionPolicy -List

Set the ExecutionPolicy for the level and scope you want, for example:

Set-ExecutionPolicy -Scope LocalMachine Unrestricted

Note that you may need to run PowerShell as administrator depending on the scope you are trying to set the policy for.

This solved it for me (on a 64-bit machine)

This answer actually led me to what was giving me the same Error message. I was running a powershell script with a scheduled task, but rather than use my windows user to run the script, I was using another account (a service account). I had to log in as that account and unrestrict the scripts for that user as well.

c# - .ps1 cannot be loaded because the execution of scripts is disable...

c# asp.net powershell
Rectangle 27 7

$WP = add-type @"
$wp

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Style                                    System.Enum
True     False    Setter                                   System.Object
Add-Type
-Passthru
$wp
Add-Type -typedef @"
...
"@
$WP = [Wallpaper.Setter]

scripting - PowerShell script fails first time but works second time -...

scripting powershell powershell-v2.0
Rectangle 27 4

In your subprocess.Popen() call, shell=True means that the platform's default shell should be used.

While the Windows world is - commendably - moving from CMD (cmd.exe) to PowerShell, Python determines what shell to invoke based on the COMSPEC environment variable, which still points to cmd.exe, even in the latest W10 update that has moved toward PowerShell in terms of what the GUI offers as the default shell.

For backward compatibility, this will not change anytime soon, and will possibly never change.

A simple Python example of how to invoke the powershell binary directly, with command-line switches followed by a single string containing the PowerShell source code to execute:

import subprocess

args = 'powershell', '-noprofile', '-command', 'set-location /; $pwd'
subprocess.Popen(args)

Note that I've deliberately used powershell instead of powershell.exe, because that opens up the possibility of the command working on Unix platforms too, once PowerShell Core is released.

Windows only: An example with shell = True, after redefining environment variable COMSPEC to point to PowerShell first:

import os, subprocess    

os.environ["COMSPEC"] = 'powershell'

subprocess.Popen('Set-Location /; $pwd', shell=True)

COMSPEC is only consulted on Windows; on Unix platforms, the shell executable is invariably /bin/sh

As of Windows PowerShell v5.1 / PowerShell Core v6-beta.3, invoking powershell with just -c (interpreted as -Command) still loads the profiles files by default, which can have unexpected side effects (with the explicit invocation of powershell used above, -noprofile suppresses that).

  • Changing the default behavior to not loading the profiles is the subject of this GitHub issue, in an effort to align PowerShell's CLI with that of POSIX-like shells.

Python Popen fails in compound command (PowerShell) - Stack Overflow

python powershell subprocess popen
Rectangle 27 5

I believe it's because-passthru is making $WP into an array - you could try this try this instead:

try {
   $WP = [Wallpaper.Setter]
} catch {
   add-type @"
....
"@
    $WP = [Wallpaper.Setter]
}

You can see by running it line by line and checking the tyoe:

PS D:\bin\OpenSSL-Win32\bin> $WP

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Style                                    System.Enum
True     False    Setter                                   System.Object

PS D:\bin\OpenSSL-Win32\bin> $WP.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array


PS D:\bin\OpenSSL-Win32\bin> $WP = [Wallpaper.Setter]
PS D:\bin\OpenSSL-Win32\bin> $WP.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
False    True     RuntimeType                              System.Type

The second time around the type is already there so %WP is loaded correctly.

Thanks for the detailed answer Matt. I've accepted stej's answer, simply because he answered first, but I've up voted both. I appreciate the extra detail explaining how to troubleshoot it.

scripting - PowerShell script fails first time but works second time -...

scripting powershell powershell-v2.0
Rectangle 27 5

The Name property gives you just the filename without the path. You probably want to use the FullName property instead. You can also simplify this since Rename-Item accepts pipeline input for the source filename:

gci E:\logs *.log | rename-item -newname {$_.FullName + ".old"}

Also note that gci (get-childitem) allows you to filter the items it outputs using the -Filter parmater. This parameter is a positional parameter (2) so you don't even have to specify the parameter name.

wow, that is waaaay easier than what I was doing. And it also works from any directory. TY!

scripting - Powershell 1.0 - Renaming files fails when script is in a ...

powershell scripting powershell-v1.0
Rectangle 27 4

I just ran the example given by powershell using "Get-Help Set-SQSQueueAttribute -Detailed", and it worked without issue.

Based on the PowerShell example working, and the specific error you received, it would suggest there is something amiss with the specific policy you are passing. I would dumb your policy down until it works, and then keep adding things incrementally until it breaks to find out what it doesnt like.

Furthermore: The Set-SQSQueueAttribute method only accepts a MAX of 7 action parameters, AND it does not accept ANY of the ones you mentioned in your code. Valid actions would be:

One thing I noticed different about your example that stood out versus the example that worked for me below is this:

"Condition": {
        "ArnEquals": {
          "aws:SourceArn": "$topicarn"
          }
      }
"Condition": {
            "StringEquals": {
                 "AWS:SourceOwner": $topicARN
            }
       }
$qurl = New-SQSQueue -QueueName "myQueue" -Region 'us-east-1' -AccessKey 'accesskey' -SecretKey 'secretkey'
$topicarn = New-SNSTopic -Name "myTopic"

$qarn = (Get-SQSQueueAttribute -QueueUrl $qurl -AttributeName "QueueArn").QueueARN

# construct the policy and inject arns
$policy = @"
{
  "Version": "2008-10-17",
  "Id": "$qarn/SQSPOLICY",
  "Statement": [
      {
      "Sid": "1",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "SQS:SendMessage",
      "Resource": "$qarn",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "$topicarn"
          }
      }
    }
  ]
}
"@

Set-SQSQueueAttribute -QueueUrl $qurl -Attribute @{ Policy=$policy }

powershell - Why does Set-SQSQueueAttribute fail with an 'InvalidOpera...

powershell amazon-web-services amazon-s3 aws-powershell
Rectangle 27 3

It seems you've already found the workaround (using the Short Name versus the FQDN), so instead I'll try to answer why you're hitting into this problem in the first place.

Some greater can be found in this blog post; effectively this is happening because when you specify the FQDN to a server, you're running afoul of one of PowerShell / Windows security features. Even though you're specifying that PowerShell should bypass the normal execution policy, running from an FQDN makes Windows believe that this file is coming from the web, and thus PowerShell wants to display a warning to you like this one:

Run only scripts that you trust. While scripts from the Internet can be
useful, this script can potentially harm your computer. Do you want to run  
\\tt-file.perf.corp\fileshare\helloworld.ps1?
[D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"):

But it cannot, because you're running the shell in NonInteractive Mode.

  • As this blog post mentions, you could resolve the problem by making the UNC path a trusted site in IE, or use only the Short Name as you've seen (using \tt-file\ versus \tt-file.perf.corp) instead.
  • You could use Group Policy (or configure within IE if this is a one-off computer) addresses for local Intranet Zone. If this is a one-off machine, go to Internet Explorer, Tools, Internet Options, then go to the Security Tab. Click Local Intranet, Advanced, then add your FQDN here, as seen below.

If this is a setting you'll want to configure globally, specify the path just like I did above at the following location within Group Policy Management Console:

User Configuration, expand Polices > Windows settings >Internet Explorer Maintenance >Security 3. Double click Security Zones and Content Ratings, then chose Import the current security zones and privacy settings.

I hope this helps! Unfortunately I can't think of a good PowerShell way to solve this problem :).

Thanks for the information, that explains it. Do you know why I wouldn't be seeing this problem on another internal domain? As far as I can tell, there is no Group Policy in place to add the domain to the local intranet, and it's not set in IE. I'm not sure where else to look to find out what might be allowing it to work.

There is a setting in Internet Explorer in the same area I mentioned before trusted sites, anyway there is a checkbox you can click that will automatically determine intranet sites and bypass the security. Perhaps that box is checked?

Executing Powershell on remove server fails when path to script is ful...

powershell windows-server-2012-r2 fully-qualified-naming
Rectangle 27 2

If all else fails, use Curl from http://curl.haxx.se . You can set everything, including certificate handling, POSTs, etc. Not subtle, but it works and handles all of the odder cases; e.g. you can set the --insecure flag to ignore certificate name issues, expiration, or test status.

http requests with powershell - Stack Overflow

powershell powershell-v2.0
Rectangle 27 2

It appears there is also a cmdlet called Read-S3Object that ends up with the same result. Had to use that.

Copy-S3object

Then the following script should work:

Import-Module "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\AWSPowerShell.psd1"

### SET ONLY THE VARIABLES BELOW ###

$accessKey = ""                                  # Amazon access key.  
$secretKey = ""                                  # Amazon secret key.
$fileContainingAmazonKeysSeparatedByNewLine = "" # Full path to a file, e.g. "C:\users\killeens\desktop\myfile.txt"
$existingFolderToPlaceDownloadedFilesIn = ""     # Path to a folder, including a trailing slash, such as "C:\MyDownloadedFiles\" NOTE: This folder must already exist.
$amazonBucketName = ""                           # the name of the Amazon bucket you'll be retrieving the keys for.

### SET ONLY THE VARIABLES ABOVE ###

$creds = New-AWSCredentials -AccessKey $accessKey -SecretKey $secretKey
Set-AWSCredentials -Credentials $creds

$amazonKeysToDownload = Get-Content $fileContainingAmazonKeysSeparatedByNewLine
$uniqueAmazonKeys = $amazonKeysToDownload | Sort-Object | Get-Unique
$startingpath = $existingFolderToPlaceDownloadedFilesIn

$uniqueAmazonKeys | ForEach-Object {
    $keyname = $_

    $fullpath = $startingpath + $keyname
    Read-S3Object -BucketName $amazonBucketName -Key $keyname -File $fullpath

    }

Obviously there would be better ways to produce this (as a function that accepts parameters, in a Powershell v4 workflow with parallel loops and a throttle count, better dealing with credentials, etc.) but this gets it done in its most basic form.

powershell - AWS Tools: Copy-S3Object script fails in 2.x with Error "...

powershell amazon-web-services amazon-s3 aws-powershell
Rectangle 27 6

Not only would that not work for an International version of Windows, it would fail if the user had edited the Registry to make their Desktop folder reside somewhere else. You can query the Registry for the file location using the REG command:

REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop

To get this into a variable use something like this:

FOR /F "usebackq tokens=3 skip=4" %%i in (`REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop`) DO SET DESKTOPDIR=%%i
FOR /F "usebackq delims=" %%i in (`ECHO %DESKTOPDIR%`) DO SET DESKTOPDIR=%%i
ECHO %DESKTOPDIR%

For me, on Windows 7, that returns Desktop REG_EXPAND_SZ %USERPROFILE%\Desktop which is correct but probably won't help the OP in his batch file, as he probably won't be able to parse the environment variable. Or would he just have to use it and it would parse itself?

Have added some code to parse the output of REG.EXE to the answer.

Thanks for the tip Dave. I'm not quite there yet though - think I'm missing something. I've updated the question to show where I've got to. If you've got any more advice, it would be appreciated.

Keep in mind that querying this from the registry is discouraged. Kb's VBScript solution is therefore the one that should be used to ensure that this works.

windows - What's the environment variable for the path to the desktop?...

windows powershell vbscript localization desktop
Rectangle 27 4

Faced the same problem on Github Desktop, tried a lot of things, but finally got issue fixed by running the following commands from powershell.

git rm --cached -r .
git reset --hard

This temporarily fixed things for me in that it discarded my uncommitted local changes but I'm still unable to discard changes via the GitHub App

github - Failed to Discard Changes - Stack Overflow

github github-desktop