PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label powershell. Show all posts
Showing posts with label powershell. Show all posts

Wednesday, December 21, 2022

[FIXED] What is the equivalent of the Bash ` (backquote/backtick) in Windows PowerShell?

 December 21, 2022     powershell, syntax     No comments   

Issue

I need the result of a command to be taken as a parameter in another command.

command /opt <another command output>

On Bash Linux I would do

command /opt `another command`

What is the equivalent of the ` symbol that works in Windows Terminal?

In particular, I am using the command

'C:\Program Files\Display\display64.exe' /listdevices | findstr 22MP55 | %{$_ -replace "- .*",""}

where findstr is the windows equivalent to grep and the final command in the pipe is the equivalent to sed. The output of this command will be 1, 2 or 3, and I need this to be passed to the %HERE in the following line

'C:\Program Files\Display\display64.exe' /device %HERE /rotate 90

The following minimal example, does not work:

FOR /F %a in ('"C:\Program Files\Display\display64.exe"  /listdevices | findstr 22MP55 | %{$_ -replace "- .*",""}') do echo "%a"

What I am doing wrong? (I am new in Windows).


Solution

Use (...), the grouping operator to pass output from a command as an argument to another command:

'C:\Program Files\Display\display64.exe' /device (
  'C:\Program Files\Display\display64.exe' /listdevices | findstr 22MP55 | %{$_ -replace "- .*",""}
) /rotate 90

Note: $(...), the subexpression operator, works too, but (...) is usually sufficient and has no side effects; you only need $(...) for multiple (;-separated) statements - see this answer for details.


As for what you tried:

  • In POSIX-compatible shells such as Bash, `...` is the legacy form of a command substitution whose modern syntax is $(...) - while PowerShell supports $(...) too, (...) is usually preferable, as noted.

  • In PowerShell, ` serves as the escape character (only), analogous to \ in POSIX-compatible shells - see the conceptual about_Special_Characters help topic.

  • Your attempts to use FOR /F %a in ... and %HERE (which should be %HERE%) relate to the legacy cmd.exe shell on Windows, not to its successor, PowerShell, whose syntax differs fundamentally.



Answered By - mklement0
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, December 19, 2022

[FIXED] What does the "@" symbol do in PowerShell?

 December 19, 2022     powershell, syntax     No comments   

Issue

I've seen the @ symbol used in PowerShell to initialise arrays.

What exactly does the @ symbol denote and where can I read more about it?


Solution

PowerShell will actually treat any comma-separated list as an array:

"server1","server2"

So the @ is optional in those cases. However, for associative arrays, the @ is required:

@{"Key"="Value";"Key2"="Value2"}

Officially, @ is the "array operator." You can read more about it in the documentation that installed along with PowerShell, or in a book like "Windows PowerShell: TFM," which I co-authored.



Answered By - Don Jones
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, December 17, 2022

[FIXED] How do I pass multiple parameters into a function in PowerShell?

 December 17, 2022     parameter-passing, powershell, syntax     No comments   

Issue

If I have a function which accepts more than one string parameter, the first parameter seems to get all the data assigned to it, and remaining parameters are passed in as empty.

A quick test script:

Function Test([string]$arg1, [string]$arg2)
{
    Write-Host "`$arg1 value: $arg1"
    Write-Host "`$arg2 value: $arg2"
}

Test("ABC", "DEF")

The output generated is

$arg1 value: ABC DEF
$arg2 value: 

The correct output should be:

$arg1 value: ABC
$arg2 value: DEF

This seems to be consistent between v1 and v2 on multiple machines, so obviously, I'm doing something wrong. Can anyone point out exactly what?


Solution

Parameters in calls to functions in PowerShell (all versions) are space-separated, not comma separated. Also, the parentheses are entirely unneccessary and will cause a parse error in PowerShell 2.0 (or later) if Set-StrictMode -Version 2 or higher is active. Parenthesised arguments are used in .NET methods only.

function foo($a, $b, $c) {
   "a: $a; b: $b; c: $c"
}

ps> foo 1 2 3
a: 1; b: 2; c: 3


Answered By - x0n
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, December 13, 2022

[FIXED] How to reference PSCredential.Empty in powershell script

 December 13, 2022     powershell, static-members, syntax     No comments   

Issue

I am trying to use empty credentials for anonymous access. How to I set a variable to empty credentials. I am trying to use PSCredential.Empty Property


Solution

Santiago Squarzon has provided the solution:

[pscredential]::Empty

is the PowerShell equivalent of C#'s PSCredential.Empty, i.e. access to the static Empty property of the System.Management.Automation.PSCredential type.


PowerShell's syntax for accessing .NET types and their - instance or static - member:

  • In order to refer to a .NET type by its literal name in PowerShell, you must specify it as a type literal, which is the type name enclosed in [...]

    • [pscredential] works as-is, even in the absence of a
      using namespace System.Management.Automation statement, because it happens to be a type accelerator, i.e. a frequently used type that you can access by a short, unqualified name (which can, but needn't be the same name as that of the type it references; e.g., [xml] is short for System.Xml.XmlDocument).

    • Generally, you either need a using namespace statement if you want to use the unqualified name only, or you need to use the namespace-qualified type name; e.g., [System.Management.Automation.PSCredential] or - given that the System. component is optional - [Management.Automation.PSCredential]

    • For a complete discussion of PowerShell's type literals, see this answer.

  • While instance members of .NET types are accessed with . (member-access operator), just like in C#, accessing static members requires a different operator: ::, the static member-access operator.

    • A distinct operator is necessary, because type literals are objects themselves, namely instances of System.Reflection.TypeInfo, so that using . accesses the latter's instance properties; e.g. [pscredential].FullName returns the type's namespace-qualified name.

Also note that, in keeping with PowerShell's general case-insensitive nature, neither type literals nor member names need be specified case-exactly.



Answered By - mklement0
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to create System.IO.StreamWriter with Encoding in Powershell?

 December 13, 2022     .net, constructor, powershell, syntax     No comments   

Issue

I'm trying to create instance of StreamWriter with UTF8 encoding in PowerShell.

$f = New-Object System.IO.StreamWriter "a.txt", $false, [System.Text.Encoding]::UTF8

This throws error: New-Object : Cannot find an overload for "StreamWriter" and the argument count: "3".

I'm trying to invoke this constructor: https://msdn.microsoft.com/en-us/library/f5f5x7kt(v=vs.110).aspx


Solution

Still, I would like to know what is wrong with my original syntax.

Your original syntax (fundamentally correctly) uses argument mode, in which arguments are, loosely speaking, evaluated as follows:

  • An argument that doesn't start with either $, (, or @ is treated as a string, even if not quoted; notably, [ is not among these special characters.

Therefore, [System.Text.Encoding]::UTF8 is interpreted as a string literal rather than as an expression that returns an System.Text.Encoding instance, and no System.IO.StreamWriter constructor whose 3rd argument is a string can be found.

  • Unfortunately, the error message only mentions the count of arguments, without indicating that an incorrect type might be the cause; this is a known problem - see GitHub issue #3658.

The correct solution, as mentioned in a comment by PetSerAl, is to enclose [System.Text.Encoding]::UTF8 in (...) so as to force its evaluation in expression mode, where it yields the desired result.

Note that the above also implies that the "..." (double quotes) around a.txt aren't necessary (but do no harm), so we get:

Note: For brevity, I've omitted the initial System. components from the full types in the following sample commands; e.g., IO.StreamWriter refers to System.IO.StreamWriter. Specifying the System. part is optional in PowerShell in most contexts.

$f = New-Object IO.StreamWriter a.txt, $false, ([Text.Encoding]::UTF8)

Note that it is the , between the individual constructor arguments that causes them to be passed as an array - i.e., a single argument - to New-Object, where it is (positionally) bound to the array-typed -ArgumentList (-Args) parameter.
As an aside: passing individual arguments positionally to separate parameters is more common, and requires spaces to separate them; e.g., Select-String foo t.txt is parsed as
Select-String -Pattern foo -Path t.txt.


Your own answer (since deleted) uses pseudo method syntax that is best avoided and only happens to work:

# AVOID: pseudo method syntax.
$f = New-Object IO.StreamWriter("a.txt", $false, [Text.Encoding]::UTF8)

Even though this looks like a method call (constructor call), it isn't, and is actually parsed as follows:

$f = New-Object IO.StreamWriter -ArgumentList ("a.txt", $false, [Text.Encoding]::UTF8)

That is, you've enclosed the original argument array in (...), which causes its elements to be parsed in expression mode, including [Text.Encoding]::UTF8, which happened to solve your problem.

Note that - unlike in argument mode - string a.txt does have to be enclosed in "..." (or '...') in expression mode.

As an aside:

  • Set-StrictMode -Version 2 or higher, among other things, prevents using pseudo-method syntax, but only (a) for two or more arguments and (b) only if the argument list ((...)) follows a command name (rather than an argument, as in the New-Object case), and (c) only if there is no space between the command name and the opening (; e.g.:
    & { Set-Strictmode -version 2; foo('a', 'b') }

Note that PSv5+ does offer a method-based way to construct objects, via the static new() method exposed on type-information objects, in which case all arguments are parsed in expression mode:

# PowerShell version 5 and above; you can use the ::new() method on types.
$f = [IO.StreamWriter]::new("a.txt", $false, [Text.Encoding]::UTF8)

A note on when [System.Text.Encoding]::UTF8 is needed:

Unlike Window PowerShell, .NET defaults to UTF-8 (which PowerShell [Core] (v6+) now does too).

  • When you read data, you therefore normally don't need to request UTF-8 encoding explicitly.

  • When you write data, passing [System.Text.Encoding]::UTF8 results in a UTF-8 file with a BOM, whereas relying on the default UTF-8 encoding creates a file without a BOM (which is better for cross-platform interoperabiliy); to request a BOM-less encoding explicitly, use [System.Text.Utf8Encoding]::new().



Answered By - mklement0
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] When can I use newlines (line breaks) in my Powershell commands to improve readability

 December 13, 2022     code-formatting, newline, powershell, syntax     No comments   

Issue

How do I know when I can use a New Lines/Carriage returns in my Powershell scripts? All of the search results when searching for this answer all point to the Output. I don't care about the output in this case. I am more interested in my ability to format my Powershell scripts for readability.

For Example. Two versions of a Powershell command line below. One works and one doesn't. What the command does is unimportant in this case. The point is I am needing to know when I'm allowed to create a new line and when I am not.

This command line Works as it's just one long single line:

& 'C:\Program Files\ArangoDB3 3.3.3\usr\bin\arangoimp.exe' --file 'C:\Program Files\ArangoDB3 3.3.3\usr\bin\tstImportJSON.json' --type json --collection users --progress true --overwrite true --server.username root --server.password password

This command line does NOT work due to the fact that there is a New Line in the middle of the script.

& 'C:\Program Files\ArangoDB3 3.3.3\usr\bin\arangoimp.exe' --file 
'C:\Program Files\ArangoDB3 3.3.3\usr\bin\tstImportJSON.json'
--type json --collection users --progress true --overwrite true
--server.username root --server.password password

In my case I'm just running different versions of the same command line after adding line breaks to see if they work or not. I know that I can begin a New Line when using an IF statement. I can also use New Lines when piping an object |. My assumption is that somewhere there is a list of Powershell scripting rules. I thought I had seen them somewhere once upon a time when I originally began getting into Powershell but no clue where it is now.


Solution

You can use ` as the line-continuation character[1] at the very end of a line (not even whitespace is allowed after it) in order to spread it across multiple lines.

Here's a simplified example:

& cmd.exe /c echo `
 hi `
 there

This is the equivalent of & cmd.exe /c echo hi there and yields hi there.

Note:

  • Since the ` character is both visually subtle and the syntax is easy to break by accidentally placing characters after it, consider using an array as an alternative - see below.

  • Individual commands must be on a single line and therefore need ` if you want to spread them across multiple lines, as shown above.

  • However, in a pipeline you may end the line with | and continue on the next line, without needing the `; e.g.:

      Get-Date | # Because the line ends with |, parsing continues on the next line.
        Select-Object Day
    
    • In PowerShell [Core] v7+, you may alternatively place the | at the start of the (very) next line:

          Get-Date  # PS v7+ only
          | Select-Object Day
      
  • Additionally, if individual arguments create a new parsing context in expression mode - such as an inherently multi-line capable (...) expression or a script block ({...}) passed to a cmdlet - you're also free to spread the expression across multiple lines; e.g.:

      1, 2, 3 | ForEach-Object { # { starts a multiline-aware context
        $_ + 1
      }
    
  • A hybrid case is an array-literal argument, which allows you to break a command after an interior element's , separator:

      Get-Date | Select-Object -Property Day,
                                         Year
    
  • Statements that start in expression mode always allow spreading across multiple lines (though embedded command-mode statements are subject to the usual limitations):

      $foo =         # an assignment is parsed in expression mode
              'bar'  
    

Alternatively, consider the use of an array[2] to pass the arguments, which allows you to use multiline expression-mode syntax to define the arguments as individual array elements beforehand:

# Construct the array of arguments (using multiline expression syntax)...
$arguments = '/c',
             'echo',
             'hi there'

# ... and pass it to cmd.exe
& cmd.exe $arguments 

Note: Array element hi there is passed as "hi there" by PowerShell: it employs automatic double-quoting to ensure that the argument is recognized as a single argument by the target program.

As an aside: for calling PowerShell commands (as opposed to external programs, as in the case at hand), consider constructing the arguments in a hashtable for use with splatting, where each entry key specifies a target parameter name and the corresponding value the parameter value (argument); e.g.:

# Define the hashtable representing the named arguments.
$argsHash = @{
  Filter = 'T*'
  File = $true
}
# Note the use of "@" instead of "$"
# Equivalent of:
#    Get-ChildItem -Filter T* -File
Get-ChildItem @argsHash

[1] ` is PowerShell's general-purpose escape character. Placed at the very end of a line, its function is subtly different: instead of escaping the newline that follows (which would mean retaining it as a literal), it effectively tells PowerShell to remove it and treat the next line as the continuation of the current one.

[2] An earlier form of this answer recommended array-based splatting, before PetSerAl pointed out that for invoking external programs it's sufficient to use an array as-is.
While splatting can be used too, its semantics are subtly different if one of the array element is --%, the stop-parsing symbol (in short: only when splatting does --% have its special meaning).
Splatting is a useful technique when calling PowerShell commands, however, primarily in its hash-table form (see previous link).



Answered By - mklement0
Answer Checked By - Timothy Miller (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, November 25, 2022

[FIXED] How 'local' are function parameters in a PowerShell module

 November 25, 2022     module, parameters, powershell, scope     No comments   

Issue

I have found a behavior in PowerShell that surprises me and for which I am looking for an explanation. Please consider the following PowerShell module named testParameter:

testParameter.psd1:

@{
   RootModule         = 'testParameter.psm1'
   ModuleVersion      = '0.1'

   FunctionsToExport  = @(
      'get-embeddedString'
   )
}

testParameter.psm1:

set-strictMode -version 3

function embed-string {

   param (
      [string] $pre,
      [string] $post
   )

  "$($pre)$text$($post)"
}


function get-embeddedString {

   param (
      [string] $text
   )

   return embed-string '>>> ' ' <<<'
}

When I call get-embeddedString foo, the function returns (or the console prints):

>>> foo <<<

I am surprised because this string is rendered in the function embed-string which does not declare a local variable named $text, does not have a parameter with that name and does not assign a value to it before it is used and I have expected the function to throw a The variable '$text' cannot be retrieved because it has not been set. error.

Apparently, embed-string chooses to use the value that $text has in get-embeddedString which I assume is in a different and unrelated scope.

I don't understand what's going on here and where the relevant documentation for this behavior is found.


Solution

Nested/Child functions have access to all the parent function's variables. You can even modify them in the child scope and they are returned to the original value in the parent.

function embed-string {
   param (
      [string] $pre,
      [string] $post
   )
    Write-Host $MyInvocation.BoundParameters
    Write-Host $MyInvocation.UnboundArguments

    Write-Host $text
    $text = "bar"

    "$($pre)$text$($post)"
}

function get-embeddedString {

    param (
       [string] $text
    )
    
    embed-string '>>> ' ' <<<'

    Write-Host $text
}

Output

[pre, >>> ] [post,  <<<]

foo
>>> bar <<<
foo

If you want to persist a change to a variable in the child function, you can use Set-Variable -Name text -Option AllScope.

Link about Nested Functions, applies to Child Functions too



Answered By - Ash
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, November 21, 2022

[FIXED] How to force Nuget Restore using Powershell?

 November 21, 2022     nuget, nuget-package-restore, package, powershell, visual-studio     No comments   

Issue

I'd like to force NuGet to restore my NuGet packages. Going to my solutions directory and type NuGet restore, even with the latest downloaded NuGet.exe doesn't work.

As explained here, I can do this in a Powershell prompt, using the Update-Package command (as I prefer not to use my Visual Studio environment).

However, my Powershell seems not to understand Update-Package, although I have a +5 version:

PowerShell Prompt> Get-Host | Select-Object Version

Version
-------
5.1.19041.1023


PowerShell Prompt> Update-Package -reinstall
Update-Package : The term 'Update-Package' is not recognized as the name of a cmdlet, function,
script file, or operable program.
Check the spelling of the name, or if a path was included, verify that 
the path is correct and try again.
At line:1 char:1
+ Update-Package -reinstall
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Update-Package:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

What can I do in order to launch Update-Package successfully in my Powershell?

Thanks in advance


Solution

Standard powershell doesn't ship have NuGet restore functionality.

If you refer to https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio, and https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore, you will see that there are 5 ways to use NuGet.

  • Visual Studio (and MSBuild.exe)
  • Visual Studio for Mac
  • dotnet CLI
  • NuGet.exe CLI
  • Package Manager Console (in Visual Studio)

There is no functionality built into powershell.

Your only options are to build on top of the above mentioned tooling.

  • Call dotnet.exe restore
  • Call nuget.exe restore
  • Call msbuild.exe restore.


Answered By - imps
Answer Checked By - David Marino (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, November 19, 2022

[FIXED] How do I send keys to an active window in Powershell?

 November 19, 2022     powershell, scripting     No comments   

Issue

I want my script to open an application and send keys to it after it's opened. Currently, if I run the script, it opens the app but does not send the keys.

If I run just the send keys after the app has already been opened, it works.

Here is what I've got so far:

Start-Process -FilePath "C:\Program Files\VMware\VMware Horizon View Client\vmware-view.exe" -Wait -WindowStyle Normal

$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('VMware')
Sleep 1
$wshell.SendKeys('~')
Sleep 3
$wshell.SendKeys('username')
Sleep 2
$wshell.SendKeys('{TAB}')
Sleep 1
$wshell.SendKeys('password')

Solution

By using -Wait with Start-Process, you're blocking the call until the launched process terminates.

Thus, your attempts to send keystrokes will invariably fail, because they'll be sent after the target program has terminated.


Therefore:

  • Don't use -Wait

  • Use -PassThru, which makes Start-Process emit a process-information object representing the newly launched process, whose .ID property contains the PID (process ID).

  • For more reliable targeting, you can pass a PID to $wshell.AppActivate()

  • The general caveat applies: sending keystrokes, i.e. simulating user input is inherently unreliable.

$ps = Start-Process -PassThru -FilePath "C:\Program Files\VMware\VMware Horizon View Client\vmware-view.exe" -WindowStyle Normal

$wshell = New-Object -ComObject wscript.shell

# Wait until activating the target process succeeds.
# Note: You may want to implement a timeout here.
while (-not $wshell.AppActivate($ps.Id)) {
  Start-Sleep -MilliSeconds 200
}

$wshell.SendKeys('~')
Sleep 3
$wshell.SendKeys('username')
Sleep 2
$wshell.SendKeys('{TAB}')
Sleep 1
$wshell.SendKeys('password')


Answered By - mklement0
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to run a PowerShell script without displaying a window?

 November 19, 2022     batch-file, powershell, scripting, silent, windows     No comments   

Issue

How is it possible to run a PowerShell script without displaying a window or any other sign to the user?

In other words, the script should run quietly in the background without any sign to the user.

Extra credit for an answer that does not use third party components :)


Solution

You can either run it like this (but this shows a window for a while):

PowerShell.exe -WindowStyle hidden { your script.. }

Or you use a helper file I created to avoid the window called PsRun.exe that does exactly that. You can download the source and exe file from Run scheduled tasks with WinForm GUI in PowerShell. I use it for scheduled tasks.

Edited: as Marco noted this -WindowStyle parameter is available only for V2 and above.



Answered By - stej
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to merge or append exported info of two different Exchange Powershell scripts?

 November 19, 2022     exchange-server, export-to-csv, mailbox, powershell, scripting     No comments   

Issue

I'm having a problem that I haven't been abble to resolve, I need to merge two scripts or append the second script exported info into the same delimited CSV file (created by the first script).

This is the first script:

Get-Mailbox -ResultSize Unlimited | Select-Object AddressBookPolicy, ProhibitSendQuota, SamAccountName, UserPrincipalName, WhenMailboxCreated, Alias, OrganizationalUnit, CustomAttribute1, DisplayName, PrimarySmtpAddress, RecipientType, RecipientTypeDetails, WindowsEmailAddress, WhenChanged, WhenCreated | export-csv -NoTypeInformation .\Mailboxes_filtered.csv -Delimiter ";" -Encoding unicode

And this the second one:

Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | Select DisplayName, StorageLimitStatus, TotalItemSize | export-csv -NoTypeInformation .\Mailboxes_filtered.csv -Delimiter ";" -Encoding unicode

PS: I'm using Exchange 2010.

I managed to get some success using "AddContent -Path .\Mailboxes_filtered.csv", but the added info appeared under the delimited cells on the CSV file instead of showing up beside and organized in the same way, I guess it happened because in this case the -Delimited ";" parameter is not accepted...

Those two scripts work, I just need to merge or append the exported info into the same CSV file.


Solution

You don't need to combine the two csv, you need to add the additional properties to each record. Since the record already has a DisplayName property, you would either need to overwrite it or change the property name to something else.

You can use calculated properties to tack on the additional properties. The flow will be take each mailbox one by one and look up the stats for that mailbox. Grab the properties you want out of the stats and add with calculated properties.

$mailboxlist = Get-Mailbox -ResultSize Unlimited | Select-Object AddressBookPolicy, ProhibitSendQuota, SamAccountName, UserPrincipalName, WhenMailboxCreated, Alias, OrganizationalUnit, CustomAttribute1, DisplayName, PrimarySmtpAddress, RecipientType, RecipientTypeDetails, WindowsEmailAddress, WhenChanged, WhenCreated 

$results = foreach($mailbox in $mailboxlist){
    $stats = Get-MailboxStatistics -Identity $mailbox.UserPrincipalName | Select DisplayName, StorageLimitStatus, TotalItemSize

    $mailbox | Select-Object *, @{n='StorageLimitStatus';e={$stats.StorageLimitStatus}}, @{n='TotalItemSize';e={$stats.TotalItemSize}}
}

$results | Export-Csv -NoTypeInformation .\Mailboxes_filtered.csv -Delimiter ";" -Encoding unicode


Answered By - Doug Maurer
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to Forloop Through A Chocolatey Package Install with something Similar to a requirements.txt

 November 19, 2022     chocolatey, package-managers, powershell, scripting, windows     No comments   

Issue

So I am using Chocolatey to help with Package installs on a computer and am wondering if there is a way to for loop through this in powershell. I am more familiar with for loops in Bash with Linux and Mac then I am with Windows, so was wondering if someone can give me some insights,

I basically am running the following scenario:

choc install <package_name> -y

And I need to install all of these packages at once:

Chocolatey v0.10.15
androidstudio 3.5.3.0
atom 1.41.0.20191029
awk 4.2.132
chocolatey 0.10.15
chocolatey-core.extension 1.3.5
chocolatey-dotnetfx.extension 1.0.1
chocolatey-visualstudio.extension 1.8.1
chocolatey-windowsupdate.extension 1.0.4
CrystalReports2010Runtime 13.0.18
curl 7.67.0
docker 99.0.0
docker-cli 19.03.3
DotNet3.5 3.5.20160716
dotnetcore-runtime 3.1.0
dotnetcoresdk 1.0.1
dotnetfx 4.8.0.20190930
filezilla 3.46.0
flashplayeractivex 32.0.0.303
flashplayerplugin 32.0.0.293
gawk 5.0.1
gimp 2.10.14
git 2.24.0
git.install 2.24.0
gitlab-runner 12.5.0
GoogleChrome 80.0.3987.116
gpg4win-vanilla 2.3.4.20191021
grafana 6.3.6
grep 2.1032
jdk8 8.0.231
jenkins-x 2.0.1082
jq 1.6
KB2533623 1.0.4
KB2919355 1.0.20160915
KB2919442 1.0.20160915
KB2999226 1.0.20181019
KB3033929 1.0.5
KB3035131 1.0.3
kubernetes-cli 1.17.0
less 5.51.0.20191024
minikube 1.6.1
mysql-odbc 5.3.12
nano 2.5.3
nodejs.install 13.3.0
openssh 8.0.0.1
openvpn 2.4.7
postgresql 12.1
postgresql12 12.1
postman 7.13.0
prometheus 2.2.1
prometheus-wmi-exporter.install 0.9.0
putty 0.73
putty.portable 0.73
python 3.8.0
python3 3.8.0
random-number-generator 3.0.0
ruby 2.6.5.1
rubymine 2019.2.4
runinbash 0.1.1
sed 4.7
teamviewer 15.0.8397
unzip 6.0
vagrant 2.2.6
vault 1.3.0
vcredist140 14.23.27820
vcredist2013 12.0.40660.20180427
vcredist2015 14.0.24215.20170201
vim 8.1.2318
visioviewer 16.0
visioviewer2016 16.0
visualstudio-installer 2.0.1
visualstudio2019community 16.3.10.0
vlc 3.0.8
Wget 1.20.3.20190531

How can I accomplish this?


Solution

When you run an external command (or any command), the output of that command can be piped into a PowerShell command. Since your command outputs single lines containing a package name, that output can be piped into Foreach-Object where each package (object in PowerShell terms) can be processed.

<package output command> | Foreach-Object { choc install $_ -y }

The current object being processed by Foreach-Object is $_ or $PSItem.



Answered By - AdminOfThings
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to Remove ReadOnly Attribute on File Using PowerShell?

 November 19, 2022     powershell, powershell-1.0, scripting     No comments   

Issue

How can I remove the ReadOnly attribute on a file, using a PowerShell (version 1.0) script?


Solution

You can use Set-ItemProperty:

Set-ItemProperty file.txt -name IsReadOnly -value $false

or shorter:

sp file.txt IsReadOnly $false


Answered By - Joey
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, November 14, 2022

[FIXED] How to suppress warning message from script when calling Set-ExecutionPolicy

 November 14, 2022     error-handling, powershell     No comments   

Issue

I am writing a script to prepare our laptops before use. It essentially installs certificates and sets the executionpolicy to AllSigned.

It gets executed by right mouse click and "Run with Powershell". This is a windows 10 standard bypass of executionpolicy and lets the script run on unmodified windows 10 machines (That's what it looks like to me at least). So I can execute my script without the need to change the executionpolicy explicitly.
After the script ran the machine is set up. I just get a warning that I want to suppress.

To do this inside the script I elevate the script to administrator rights with a bypass parameter. This works fine except that I get a warning when setting the AllSigned execution policy. It says that I have a policy defined at a more specific scope.

Note: The command worked and the execution policy is set. It just pops up red and looks like an error. If someone else executes the script I don't want to have questions popping up.

--My question:--
As I know that this behavior is intended I don't want the warning from showing up. How can I suppress the message?

I tried various settings with the switches "WarningAction" and "ErrorAction" but it does not work.

Some Details:
ErrorMessage:

Set-ExecutionPolicy : Windows PowerShell updated your execution policy successfully, but the setting is overridden by a policy defined at a more specific scope. Due to the override, your shell will retain its current effective execution policy of Bypass. Type "Get-ExecutionPolicy -List" to view your execution policy settings. For more information please see "Get-Help Set-ExecutionPolicy". At C:\Users\uwe\Desktop\InstallRootCA\InstallRootCertificate.ps1:46 char:5 + Set-ExecutionPolicy AllSigned -Scope LocalMachine -Force + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (:) [Set-ExecutionPolicy], SecurityException + FullyQualifiedErrorId : ExecutionPolicyOverride,Microsoft.PowerShell.Commands.SetExecutionPolicyCommand

Relevant Code parts from powershell script:

Elevating the script prior to execution:

 if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
     Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
     exit;
 }

Setting the Executionpolicy at the end of the script:

Set-ExecutionPolicy AllSigned -Scope LocalMachine

I tried all kinds of flags

-Force
-WarningAction Ignore|SilentlyContinue
-ErrorAction same

But still the red warning pops up.


Solution

You can put this command into a try catch statement. The catch statement will handle the errors and if it is empty, nothing will happen if Set-ExecutionPolicy throws an error.

try{
    Set-ExecutionPolicy AllSigned -Scope LocalMachine
}
catch {
    #Do Nothing
}

Please test it, let me know if it worked and if it did, please mark the post as the answer :)



Answered By - Nicicalu
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I display a 'naked' error message in PowerShell without an accompanying stacktrace?

 November 14, 2022     error-handling, exit-code, powershell, stderr     No comments   

Issue

How can I write to standard error from PowerShell, or trap errors such that:

  • An error message is displayed as an error (truly writing to standard error so that TeamCity and Octopus see it as an error)
  • No stack trace garbage muddles my beautiful, concise error message

All these years I've survived by throwing errors or writing via Write-Error, but I'm tired and old, and in my scripts I just want to see one concise error message. I've been trying every combination of trap, throw, Write-Error, and -ErrorAction, to no avail:

try {
  throw "error" # Sample code for a stack overflow. In the theater
  # of your mind, imagine there is code here that does something real and useful
} catch {
  Write-Error "An error occurred attempting to 'do something.' Have you tried rebooting?"
}

Here's the user experience I want to see:

C:\> & .\Do-Something.ps1
An error occurred attempting to 'do something.' Have you tried rebooting?

C:\> ▏

Instead I get:

C:\> & .\Do-Something.ps1
An error occurred attempting to 'do something.' Have you tried rebooting?
At line:1 char:1
+ Do-RealWork
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Do-RealWork

C:\> ▏

Solution

Setting the automatic $ErrorView variable to 'CategoryView' causes PowerShell to output concise, single-line error representations instead, but this representation may not always include enough information, because the error message is typically not included; on the plus side, the text passed to Throw "..." is reflected, but, by contrast, Write-Error output contains no specific information while 'CategoryView' is in effect.
Adding a new error view to PowerShell that is single-line yet always contains all crucial information is being discussed for v6.

Provided that your PowerShell code is run from a console (uses a console host), use [Console]::Error.WriteLine(), which unconditionally writes to the outside world's stderr (standard error stream):

[Console]::Error.WriteLine("An error occurred ... Have you tried rebooting?")

Note:

  • This won't work from non-console hosts such as the PowerShell ISE.

  • [Console]::Error.WriteLine() output doesn't print in red in the console [1].


Sadly, there is no single solution that works both from within PowerShell (across hosts) and from outside of it:

  • [Console]::Error.WriteLine(), while writing properly to stderr for the outside world, cannot have its output captured or suppressed inside PowerShell, and only works with the PowerShell console host.

  • Similarly, $host.ui.WriteErrorLine(), even though works with all hosts, it is a UI method that works outside PowerShell's stream system as well and therefore its output too cannot be captured or suppressed in PowerShell.
    More importantly, it doesn't write to the outside world's stderr (it behaves like Write-Error in this respect, see below).

  • Inside PowerShell, only Write-Error writes to PowerShell's error stream, so its output can be captured / suppressed.
    However, unfortunately, Write-Error (apart from being noisy) does not write to the outside world's stderr, unless, bizarrely, stderr is explicitly being redirected - see this answer of mine for details.


[1] Peter (the OP himself) offers a workaround for that:

[Console]::ForegroundColor = 'red'
[Console]::Error.WriteLine("An error occurred ... Have you tried rebooting?")
[Console]::ResetColor()

suneg's helpful answer provides a function wrapper for it.

Fortunately, PowerShell automatically omits the color codes when it detects that the output is being redirected (to a file).



Answered By - mklement0
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to log copied files and check network availability with powershell?

 November 14, 2022     copy, error-handling, logfile, move, powershell     No comments   

Issue

I'm currently working on my first powershell script and can't make any progress.

The aim of the script is that I can automatically move or copy files from one network drive to another at a specific time. And the whole thing should be logged. My code so far looks like this:

Param(
    [string]$src,    
    [string]$trgt,
    [string]$log,
    [string]$plot
)

<# 
try {
     New-SmbMapping -LocalPath $src -RemotePath $trgt -Persistent $True
    } catch {
     Write-Host "There was an error mapping $src to $trgt"
}
#>
# New-SMBMapping -Localpath $src -Remotepath $trgt -persistent $true

Start-Transcript $log

if ($plot -eq "copy")
{
    Copy-Item -Path $src -Destination $trgt -Recurse
    Write-Host -ForegroundColor Green "copy finished."
    Stop-Transcript
}

elseif ($plot -eq "move")
{
    Move-Item -Path $src -Destination $trgt
    Write-Host -ForegroundColor Green "move finished."
    Stop-Transcript
}

First of all, I'm still missing error handling here, in case something shouldn't work. If, for example, the source path or the target path, i.e. the network drives, are not available. How can I check if a network drive is available?

And secondly, I'm not really able to log rightly yet. I would like to record in a log file what is moved or copied where and when.

Can someone help me?


Solution

In case of error handling try/catch - as you did - is the right way to go, you may set the erroraction to stop -erroraction:stop to ensure any error is returned as terminating error because try/catch will only consider those. Also if you catch an error you should return an error by using write-error instead of write-host, and also include the exception message returned by the cmdlet:

try {
    New-SmbMapping -LocalPath $src -RemotePath $trgt -Persistent $True -ErrorAction:stop
}
catch {
    write-error "There was an error mapping $src to $trgt - Exception: $_"
}

In case of logging, you may add the parameter -passthru which returns the result of the operation. By doing so you can collect the operation result in variable and write it to the logfile, e.g.:

if ($plot -eq "copy"){
    try {
        $result = Copy-Item -Path $src -Destination $trgt -Recurse -PassThru -ErrorAction:stop
        "copy item $src to $result.fullname" | Add-Content -Path [logfilepath]
    }
    Catch {
        write-error "Failed to copy file: $src to $trgt - Exception: $_"
        "Failed to copy item: $src to $trgt - Exception: $_" | Add-Content -Path [logfilepath]
    }
}
elseif ($plot -eq "move"){
    try {
        $result = Move-Item -Path $src -Destination $trgt -PassThru -ErrorAction:stop
        "move item $src to $result.fullname" | Add-Content -Path [logfilepath] 
    }
    Catch {
        write-error "Failed to move file: $src to $trgt - Exception: $_"
        "Failed to move file: $src to $trgt - Exception: $_" | Add-Content -Path [logfilepath]
    }
}

But in the current scenario move/copy-item does not return you more information as you already did know (source/destination). Also if you process a batch of files and not only a single item it may be better to collect the operation results in a array and write it after the processing one time to the disk...



Answered By - Toni
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I change the default PowerShell error for when a command needs elevation?

 November 14, 2022     elevation, error-handling, function, powershell, windows-11     No comments   

Issue

I have a lot of code in a PowerShell script that are mix of commands that need elevation to run and commands that don't, those that need elevation show errors in PowerShell console like:

"You don't have enough permissions to perform the requested operation"

and

 "Requested registry access is not allowed."

is there a way to globally suppress only the kinds of errors that PowerShell shows due to lack of necessary privileges?

I thought about a function that checks for elevation and performs actions based on the result, like this:

https://devblogs.microsoft.com/scripting/use-function-to-determine-elevation-of-powershell-console/

Function Test-IsAdmin

{    
   
 $identity = [Security.Principal.WindowsIdentity]::GetCurrent()

 $principal = New-Object Security.Principal.WindowsPrincipal $identity

 $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)

   }

and

if(-NOT (Test-IsAdmin))

   { write-host "Skipping Admin command" }

else { $code }

but I don't know how to apply it globally to the whole script, so that commands that don't need elevation run, and those that need elevation show a custom message or skip that part silently.

another thing that can help my situation would be to find out if a PowerShell command needs elevation before actually running it and causing it to show errors in console due to lack of privileges.


Solution

It seems that errors stemming from a lack of privileges typically - but not necessarily - involve a System.UnauthorizedAccessException or System.Security.SecurityException .NET exception behind the scenes, whose name is then reflected as part of the .FullyQualifiedErrorId property of the resulting PowerShell error record, which is of type System.Management.Automation.ErrorRecord.

Assuming that this applies to all errors you care about, you can use a (rarely used anymore) trap statement as follows:

trap {
  if ($_.FullyQualifiedErrorId -match 'UnauthorizedAccessException|SecurityException') { 
    Write-Warning "Skipping admin command ($($_.InvocationInfo.Line.Trim()))"
    continue # Suppress the original error and continue.
  }
  # If the error was created with `throw`, emit the error and abort processing.
  # SEE CAVEAT BELOW.
  elseif ($_.Exception.WasThrownFromThrowStatement) { break }
  # Otherwise: emit the error and continue.
}

# ... your script

Caveat:

  • If your script implicitly raises script-terminating errors - via -ErrorAction Stop or $ErrorActionPreference = 'Stop' - the above solution in effect turns them into statement-terminating errors and continues execution (only explicit script-terminating errors created with a throw statement are recognized as such in the code above, and result in the script getting aborted).

  • Unfortunately, as of PowerShell 7.2.x, there is no way to generally discover whether a given error is (a) non-terminating, (b) statement-terminating or (c) script-terminating (fatal).

    • See GitHub issue #4781 for a proposal to add properties to [System.Management.Automation.ErrorRecord] to allow such discovery in the future.


Answered By - mklement0
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How To Get Exit Code From PowerShell Script

 November 14, 2022     error-handling, exit-code, powershell, try-catch     No comments   

Issue

I'm trying to write a PowerShell script which sends a Slack notification whenever our build system in unable to push Docker images to Docker Hub. How can I detect and handle the Process exited with code 1 from the docker push command? I've tried the following, but the catch block isn't called.

try {
  docker push $dockerImage;
}catch{
  #Send error details to Slack
}

Solution

  • As of PowerShell 7.3, calls to external programs (such as docker) never cause a statement-terminating error[1] that you can trap with try / catch; similarly, stderr output from external program is (rightfully) not considered error output by PowerShell, and therefore $ErrorActionPreference = 'Stop' has no effect on it (for legacy exceptions in Windows PowerShell, see this answer).

    • However, opt-in integration with PowerShell's error handling may be implemented in the future; as of v7.3, there is an experimental feature named PSNativeCommandErrorActionPreference (which may become an official feature):

      • If this feature is enabled (Enable-ExperimentalFeature PSNativeCommandErrorActionPreference) and the associated $PSNativeCommandErrorActionPreference preference variable is set to $true, any external-program call that reports a nonzero exit code automatically triggers a PowerShell error in response (obviating the need for explicit $LASTEXITCODE -ne 0 checks), which then integrates with PowerShell's own error handling.[2]
    • In general, note that a statement-terminating PowerShell error (which can be caught with try / catch) does occur if PowerShell fails to even launch a command, such as when you supply a non-existent executable name or path; e.g.:

      try   { nosuchexe foo bar }
      catch { Write-Warning "Failed to invoke nosuchexe: $_" }
      
  • The automatic $LASTEXITCODE variable reflects the process exit code of the most recently executed external program. By convention, exit code 0 signals success, anything else an error condition.

Therefore:

docker push $dockerImage
if ($LASTEXITCODE -ne 0) {
  #Send error details to Slack
}

See also:

  • This answer has more information on exit-code processing in PowerShell.

[1] The only exception is a bug, present up to PowerShell 7.1, where the combination of redirecting stderr output (2> or *>) with $ErrorActionPreference = 'Stop' unexpectedly causes a script-terminating error if there's actual stderr output - see this answer.

[2] Unfortunately, as of v7.3.0, the automatically triggered PowerShell error is a non-terminating error rather than a statement-terminating one; the latter would make more sense, as it would allow it to be selectively caught with a try statement - see GitHub issue #18368.



Answered By - mklement0
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, November 5, 2022

[FIXED] How to get Powershell to run SH scripts

 November 05, 2022     environment-variables, powershell, scripting, sh     No comments   

Issue

Can someone please tell me how I get Powershell to run .sh scripts? It keeps just trying to open the file i need in Notepad when I run this command:

.\update-version.sh 123

I've added .SH to my PATHEXT environment variable and also added the Microsoft.PowerShell_profile.ps1 directory to the Path environment variable.


Solution

PowerShell scripts have a .ps1 extension (along with other supported extensions such as psm1,psd1 etc) it will not run other extensions other than that.



Answered By - Shay Levy
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, October 31, 2022

[FIXED] Why is this PowerShell code (Invoke-WebRequest / getElementsByTagName) so incredibly slow on my machines, but not others?

 October 31, 2022     performance, powershell, powershell-3.0     No comments   

Issue

I wrote some screen-scraping code in PowerShell and was surprised that it took around 30 seconds to parse a few HTML tables. I stripped it down to try and figure out where all the time was being spent, and it seems to be in the getElementsByTagName calls.

I've included a script below which on both my home desktop, my work desktop and my home slate, takes around 1-2 seconds for each iteration (full results pasted below). However, other people in the PowerShell community are reporting far shorter times (only several milliseconds for each iteration).

I'm struggling to find any way of narrowing down the problem, and there doesn't seem to be a pattern to the OS/PS/.NET/IE versions.

The desktop I'm currently running it on is a brand new Windows 8 install with only PS3 and .NET 4.5 installed (and all Windows Update patches). No Visual Studio. No PowerShell profile.

$url = "http://www.icy-veins.com/restoration-shaman-wow-pve-healing-gear-loot-best-in-slot"
$response = (iwr $url).ParsedHtml

# Loop through the h2 tags
$response.body.getElementsByTagName("h2") | foreach {

    # Get the table that comes after the heading
    $slotTable = $_.nextSibling

    # Grab the rows from the table, skipping the first row (column headers)
    measure-command { $rows = $slotTable.getElementsByTagName("tr") | select -Skip 1 } | select TotalMilliseconds
}

Results from my desktop (the work PC and slate give near identical results):

TotalMilliseconds
-----------------
        1575.7633
        2371.5566
        1073.7552
        2307.8844
        1779.5518
        1063.9977
        1588.5112
        1372.4927
        1248.7245
        1718.3555
         3283.843
        2931.1616
        2557.8595
        1230.5093
         995.2934

However, some people in the Google+ PowerShell community reported results like this:

 TotalMilliseconds
 -----------------
           76.9098
          112.6745
           56.6522
          140.5845
           84.9599
           48.6669
           79.9283
           73.4511
           94.0683
           81.4443
           147.809
          139.2805
          111.4078
           56.3881
           41.3386

I've tried both PowerShell ISE and a standard console, no difference. For the work being done, these times seem kinda excessive, and judging by the posts in the Google+ community, it can go quicker!


Solution

See my comment in: https://connect.microsoft.com/PowerShell/feedback/details/778371/invoke-webrequest-getelementsbytagname-is-incredibly-slow-on-some-machines#tabs

I got the same slowness running the script in 64 bits, but when running in 32bits mode, everything is very fast !

Lee Holmes was able to reproduce the issue, and here is his writeup

"The issue is that he’s piping COM objects into another cmdlet – in this case, Select-Object. When that happens, we attempt to bind parameters by property name. Enumerating property names of a COM object is brutally slow – so we’re spending 86% of our time on two very basic CLR API calls:

(…) // Get the function description from a COM type typeinfo.GetFuncDesc(index, out pFuncDesc); (…) // Get the function name from a COM function description typeinfo.GetDocumentation(funcdesc.memid, out strName, out strDoc, out id, out strHelp); (…)

We might be able to do something smart here with caching.

A workaround is to not pipe into Select-Object, but instead use language features:

# Grab the rows from the table, skipping the first row (column headers)
$allRows = @($slotTable.getElementsByTagName("tr"))
$rows = $allRows[1..$allRows.Count]

"



Answered By - Personne
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing