Multiple Variables for "-name" parameter in "New-Item" - powershell

I'm having issues with the following PS script:
New-Item -name $InfoLog -path $LogPath -Name ("Info Log - ",$DateStamp," - ",$TimeStamp) -type file
It gives me the error-
Cannot bind parameter because parameter 'Name' is specified more than
once. To provide multiple values to parameters that can accept
multiple values, use the array syntax. For example, "-parameter
value1,value2,value3".
Any ideas? I also tried it without the parentheses.

All PowerShell cmdlets accept only one argument per parameter. However, you passed two arguments to the -Name parameter of New-Item:
New-Item -name $InfoLog -path $LogPath -Name ("Info Log - ",$DateStamp," - ",$TimeStamp) -type file
# One argument ^^^^^^^^ Another argument ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Because this is an illegal function call, PowerShell is raising your error.
It looks like you meant to write this:
New-Item -Path $LogPath -Name "Info Log - $DateStamp - $TimeStamp" -Type File
The variables in the string "Info Log - $DateStamp - $TimeStamp" will be expanded into the values that they represent:
PS > $a = 123
PS > $b = "abc"
PS > "$a -- $b"
123 -- abc
PS >

Related

How to pass the full path of a file as an argument to a new instance of Powershell?

This is the code of my script that calls another script:
$LocalFolder = "$env:USERPROFILE\Desktop\Banana Productions"
$RenderClient = "$LocalFolder\Render\Modelo 02\Cliente 02"
$CutFolder = "$RenderClient\Cortar"
$FFMpegScript = "$CutFolder\ffmpeg crop.ps1"
gci "$RenderClient\Cortar" *.mp4 -File -Recurse | ForEach-Object {
$FilePath = $_.FullName
start PowerShell "-NoExit", "-File", "`"$FFMpegScript`"", "$FilePath"
Write-Host $FilePath
}
The issue is that I am not able to pass the argument with the value of $_.FullName to the new instance, I get an error message in the new instance with the message:
Cannot process argument because the value of argument "name" is not valid
This is all that's in the script I'm calling:
param($args)
Write-Host $args[0]
Read-Host -Prompt "Press Enter to continue"
How can I resolve this?
Due to a long-standing bug in Start-Process - see GitHub issue #5576 - it is best to pass a single string argument to the (positionally implied) -ArgumentList parameter, which allows you to control the process command line explicitly:
The following uses an expandable here-string for syntactic convenience:
Get-ChildItem "$RenderClient\Cortar" -Filter *.mp4 -File -Recurse |
ForEach-Object {
$FilePath = $_.FullName
Start-Process PowerShell #"
-NoExit -File "$FFMpegScript" "$FilePath"
"# # Note: This must be at the very start of the line.
}
Additionally, do not use the automatic $args variable as a custom variable.
In fact, if you want your script to receive positional arguments only, there is no need for a formal param(...) declaration - just use the array-valued $args variable as-is:
# Without a param(...) declaration, $args *implicitly* contains
# any arguments passed, as an array.
$args[0] # output the 1st argument passed.
Read-Host -Prompt "Press Enter to continue"

How to use New-Item with $Version to create a text file

I have pulled some information from the registry using Get-ItemPropertyValue and would like to use this to create a text file with that value.
$Version = (Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name 'DisplayVersion')
Example output - 21H1
Trying to use New-Item with $Version output to create a text file, 21H1.txt
Use your variable in an expandable string, and pass the resulting string value to New-Item's -Name parameter
New-Item -Name "${Version}.txt"

Set a value for a DWORD32 value in the registry only if it already exists | PowerShell

I want to set a value for DWORD32 value in the registry only if it already exists.
This is my code:
Set-ItemProperty -Path $mypath -Name $myname -Value 0
The problem with this code is in the Set-ItemProperty class; It creates the DWORD32 value even if it doesn't exist, and I want to change its value only if it exists.
Any solutions?
Check if Get-ItemPropertyValue returns any success output while ignoring any errors (in PSv4-, use Get-ItemProperty):
if ($null -ne (Get-ItemPropertyValue -ErrorAction Ignore -LiteralPath $mypath -Name $myname)) {
Set-ItemProperty -LiteralPath $mypath -Name $myname -Value 0
}
Note:
The above just tests whether the registry value exists - it doesn't check its data type. For the latter, you could use (the value returned by Microsoft.Win32.RegistryKey.GetValueKind() is of type Microsoft.Win32.RegistryValueKind):
(Get-Item -LiteralPath $path).GetValueKind($myName) -eq 'Dword'
Note that use of Test-Path is not an option in this case, because it can only test for provider items (which map to registry keys), not also their properties (which map to registry values).

PowerShell - How to Concatenate variable with text? on same line on text file

I'm having difficulties to join a text with 1 string how do I make this join without breaking line in power shell? can you help me.
I Want This:
> PlaybackDevice=AudioDevice
> RingerDevice=AudioDevice
> RecordDevice=AudioDeviceRecord
But i have this on execute:
PlaybackDevice=
$audio.Name
RingerDevice=
$audio.Name
RecordDevice=
$mic.Name
This is my code:
Add-Content "C:\burn.txt*" "RingerDevice=" $audio.Name
Add-Content"C:\burn.txt*" "RecordDevice=" $mic.Name
Add-Content "C:\burn.txt*" "PlaybackDevice=" $audio.Name
try this
Add-Content "C:\burn.txt*" "RingerDevice=$($audio.Name)"
Add-Content "C:\burn.txt*" "RecordDevice=$($mic.Name)"
Add-Content "C:\burn.txt*" "PlaybackDevice=$($audio.Name)"
"*" is not allowed in the a hard drive path. You must put ALL of content you want to write in "" or ''. Given that you have a variable such as "$audio.Name" it is treated as a object that has a label called "name" and a value called "logictech" in my example below. Add-Content only wants the value by using $() you can expand the variable and only give the value. e.g. $($audio.Name). Never write to the C:\ path. It is block in many places for security reasons. Run the code below for a working example.
$audio = [PSCustomObject]#{
Name = "logictech"
}
$mic= [PSCustomObject]#{
Name = "MyMic"
}
Add-Content -path "$env:temp\burn.txt" -Value "RingerDevice=$($audio.Name)"
Add-Content -Path "$env:temp\burn.txt" -Value "RecordDevice=$($mic.Name)"
Add-Content -Path "$env:temp\burn.txt" "PlaybackDevice=$($audio.Name)"
sleep 10
Start-Process "$env:temp\burn.txt"

How to set a binary registry value (REG_BINARY) with PowerShell?

How to set a binary registry value (REG_BINARY) with PowerShell?
Background:
I need to change some properties of the ASP.NET State service using a PowerShell script. Unfortunately, the built-in PowerShell cmdlet Set-Service only lets you modify the service description, startup type, display name, and status. I need to modify the Subsequent failures property found on the Recovery tab (when viewing the service's properties). I found that this value was stored in the registry as a REG_BINARY value.
An export of the value looks like this:
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\aspnet_state]
"FailureActions"=hex:50,33,01,00,00,00,00,00,00,00,00,00,03,00,00,00,0e,00,00,\
00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00
In Powershell there is a Set-ItemProperty cmdlet with which you can set registry value values. For a string or dword value, you can just pass a string or an int. I know which hex value in the array to change, but I can't figure out how to set a binary value.
The following line gives you an example how to create one
New-ItemProperty -Path . -Name Test -PropertyType Binary -Value ([byte[]](0x30,0x31,0xFF))
and how to change an existing one:
Set-ItemProperty -Path . -Name Test -Value ([byte[]](0x33,0x32,0xFF))
Is it just me who feels this misses the main part of this question?
How would you go about changing the original:
50,33,01,00,00,00,00,00,00,00,00,00,03,00,00,00,0e,00,00,\
00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00
Into a format like:
([byte[]](0x33,0x32,0xFF))
EDIT: After trying to get this working it turns out you just prefix all of the pairs with '0x'. Not sure why that was not mentioned in the answer. So just change the above to:
0x50,0x33,0x01,0x00,0x00,0x00,0x00,0x00... etc.
Then wrap that in the following:
([byte[]](0x50,0x33,0x01,0x00,0x00,0x00,0x00,0x00... etc.))
This post has helped me out with similar problem. Thanks!
Bringing xBr0k3n and Howard's answers together:
#Change these three to match up to the extracted registry data and run as Admin
$YourInput = "50,33,01,00,00,00,00,00,00,00,00,00,03,00,00,00,0e,00,00,00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00"
$RegPath = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\aspnet_state'
$AttrName = "FailureActions"
$hexified = $YourInput.Split(',') | % { "0x$_"}
New-ItemProperty -Path $RegPath -Name $AttrName -PropertyType Binary -Value ([byte[]]$hexified)
Resurrecting this.
Here's how you can modify registry item binary values concisely in easy-to-follow powershell. In this example DefaultConnectionSettings is the registry item with a REG_BINARY value that we're trying to modify.
$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"
$objName = "DefaultConnectionSettings"
$getObj = Get-ItemProperty -path $path -name $objName
$getObj.DefaultConnectionSettings[8] = 1
$objValue = $getObj.DefaultConnectionSettings
Set-ItemProperty -path $path -name $objName -Value $objValue
When you use Get-ItemProperty for a registry item with a REG_BINARY value, it gives you a number of child objects in a collection.
By referencing the name of the item (in this case we do getObj.DefaultConnectionSettings) as a child object of getObj, we get an array of values, where each binary value (i.e 50,33,01,00,00,00,00,00,04) has its own position in the array.
Because it is an array we can reference, modify, and iterate through it easily by doing $getObj.DefaultConnectionSettings[8] = 1 or whatever number you want in place of 8. The 8 refers to the position of the value in the array. In the example of 50,33,01,00,00,00,00,00,04 the 9th position is 04. Remember that, like other things, arrays start counting at 0.
Setting it = 1 will change that 04 value in the binary to 01 while leaving the rest of the values unchanged in the array.
Finally, we set the change in place with Set-ItemProperty -path $path -name $objName -Value $objValue
Hope this helps others.
FYI, you can also set binary values with the PSRemoteRegistry PowerShell module (
http://psremoteregistry.codeplex.com/), on local or remote computers.
$Key = 'SOFTWARE\MyCompany'
Set-RegBinary -Hive LocalMachine -ComputerName Server1 -Key $Key -Value RegBinary -Data #([char[]]'PowerShell')
Let's start with an integer:
$int = 0xffffffff
Get the bytes:
$bytes = [bitconverter]::GetBytes($int)
Using set-itemproperty with the little knows '-type' parameter that can be used with registry paths:
Set-ItemProperty hkcu:\key1 bin1 $bytes -type binary
Get it back:
$bytes = Get-ItemProperty hkcu:\key1 bin1 | % bin1
Turn 4 bytes into an int:
$int = [bitconverter]::toint32($bytes, 0)
'0x{0:x}' -f $int
0xffffffff
I had problems with the other solutions, here's what I found to work:
Short Answer:
New-ItemProperty -path $path -name $name -value [byte]0x00,0x01,0x02 -PropertyType Binary
Complete Example:
$path = "HKCU:\Software\Hex-Rays\"
$name = "StrWinStringTypes"
$value = [byte]0x00,0x01,0x02
#if key path found, just add/modify the value/data pair
If (Test-Path($path))
{
New-ItemProperty -path $path -name $name -value $value -PropertyType Binary -Force | Out-Null
}
#if key path not found, create it first before adding value/data
Else
{
New-Item -path $path -force
New-ItemProperty -path $path -name $name -value $value -PropertyType Binary -Force | Out-Null
}