I am trying to convert a phong material to mia material using this script i found
proc connectAndSet(string $original,string $target){
$conn=connectionInfo -sfd ($BARK3);
if ($conn!=""){
connectAttr -force $conn $target;
} else {
connectAttr -force $original $target;
disconnectAttr $original $target;
}
}
proc convertPhongToMia(string $original){
$target=`mrCreateCustomNode -asShader "" mia_material`;
connectAndSet($original+".color",$target+".diffuse");
$sg=`connectionInfo -dfs ($original+".outColor")`;
if ($sg[0]!=""){
$sgr=`match "[^.]*" ((string)$sg[0])`;
connectAttr -force ($target+".outValue") ($sgr+".miMaterialShader");
connectAttr -force ($target+".outValue") ($sgr+".miPhotonShader");
connectAttr -force ($target+".outValue") ($sgr+".miShadowShader");
}
delete $original;
rename $target $original;
}
for ($item in`ls -et phong`)
convertPhongToMia($item)
I am a total noob on mel scripting so i have no idea why its not working or how to fix it
it is showing the folowing errors:
// Error: $conn=connectionInfo -sfd ($BARK3); //
// Error: Line 2.24: Invalid use of Maya object "connectionInfo". //
// Error: $conn=connectionInfo -sfd ($BARK3); //
// Error: Line 2.36: "$BARK3" is an undeclared variable. //
// Error: if ($conn!=""){ //
// Error: Line 3.13: "$conn" is an undeclared variable. //
// Error: connectAttr -force $conn $target; //
// Error: Line 4.36: "$conn" is an undeclared variable.
$BARK3 is the name of the material im trying to convert
// you need to define $BARK some where
proc connectAndSet(string $original,string $target, $BARK){
// when you call mel function you need to use `
$conn=`connectionInfo -sfd ($BARK)`;
if ($conn!=""){
connectAttr -force $conn $target;
} else {
connectAttr -force $original $target;
disconnectAttr $original $target;
}
}
....
$target=`mrCreateCustomNode -asShader "" mia_material`;
$BARK = "someNode";
connectAndSet($original+".color",$target+".diffuse", $BARK);
Related
Need help troubleshooting an the Array and Scriptblock
OR Maybe this is better using param and functions???
Script Objective: To easily update the list of applications to be installed
Getting error below.
'
At C:\Temp\appinstall.ps1:7 char:10
$Firefox={
~
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept
assignments, such as a variable or a property.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : InvalidLeftHandSide
'
Start-Transcript -Append c:\Deploy\log.txt
$ProgressPreference = 'SilentlyContinue';
#Change App Name, Source, MSI/EXE, Argument
$AppArray= (
$Firefox={
$App= "Firefox";
$App_source= "https://download.mozilla.org/?product=firefox-latest&os=win64&lang=en-US";
$destination = "c:\Deploy\$App.exe";
$Argument= "/S";
},
$Chrome=
{
$App= "Chrome";
$App_source= "https://dl.google.com/tag/s/defaultbrowser/edgedl/chrome/install/GoogleChromeStandaloneEnterprise64.msi";
$destination = "c:\Deploy\$App.exe";
$Argument= "/norestart","/qn";
}
)
$InstallScriptBlock=
{
$installed = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where { $_.DisplayName -Match "$App" });
$installed.displayname
if ($installed.displayname -Match $App) {
Write-Host "$software installed"
}else{
If ((Test-Path $destination) -eq $false) {
New-Item -ItemType File -Path $destination -Force
}
#install software
Invoke-WebRequest $App_source -OutFile $destination
Start-Process -FilePath "$destination" -ArgumentList "$Argument" -Wait
#Delete installer
Remove-Item -recurse "$destination"
}
}
ForEach ($Program in $AppArray) {Invoke-Command -ScriptBlock $InstallScriptBlock}
Stop-Transcript
It looks like you're trying to create a nested hashtable (#{ ... }), but your syntax is flawed - see the linked docs.
However:
It should suffice in your case to create an array of hashtables to iterate over with foreach
There's no need to use a separate script block ({ ... }) - just use the body of the foreach loop statement.
As an aside: While using Invoke-Command for local invocation of script blocks works, it usually isn't necessary, because &, the call operator, will do (e.g. $sb = { 'hi' }; & $sb). Invoke-Command's primary purpose is to execute a script block on a remote machine.
Generally, you can use variables as-is as command arguments, without enclosing them in "..." - even if their values contain spaces. E.g., Write-Output $foo is sufficient, no need for Write-Output "$foo"
To put it all together:
# Create an array whose elements are hashtables.
$appArray = (
#{
App = ($thisApp = 'Firefox')
App_source = 'https://download.mozilla.org/?product=firefox-latest&os=win64&lang=en-US'
Destination = "c:\Deploy\$thisApp.exe"
Argument = '/S'
},
#{
App = ($thisApp = 'Chrome')
App_source = 'https://dl.google.com/tag/s/defaultbrowser/edgedl/chrome/install/GoogleChromeStandaloneEnterprise64.msi'
Destination = "c:\Deploy\$thisApp.exe"
Argument = '/norestart /qn'
}
)
foreach ($app in $appArray) {
# Note how $app.<key> is used to refer to the entries of the hashtable at hand,
# e.g. $app.App yields "Firefox" for the first hashtable.
$installed = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -Match $app.App }
$installed.displayname
if ($installed.displayname -Match $app.App) {
Write-Host "$($app.App) already installed."
}
else {
if ((Test-Path $app.Destination) -eq $false) {
New-Item -ItemType File -Path $app.Destination -Force
}
#install software
Invoke-WebRequest $app.App_source -OutFile $app.Destination
Start-Process -FilePath $app.Destination -ArgumentList $app.Argument -Wait
#Delete installer
Remove-Item -Recurse $app.Destination
}
}
Note:
I've removed unnecessary ; and I've switched to using verbatim (single-quoted) strings ('...') when no string interpolation via expandable (double-quoted) strings ("...") is required, both for conceptual clarity and to avoid potentially unwanted expansions.
Note the use of aux. variable $thisApp in the App key, which allows referencing it in the later Destination key, in an expandable string ("c:\Deploy\$thisApp.exe").
GitHub suggestion #13782 looks for a more elegant way to allow hashtable entries to reference one another.
on a local Server I've got a bunch of sub-folders containing PowerShell-scripts, one of those is "sqlserver" folder contains Microsoft sqlserver module. I've got a daily task-scheduler job connecting a sql-server, there is a zip-file having the same sub-folder structure (with a folder: sqlserver) as on the local server.
The idea is to overwrite the local folder structure with the new structure from the zip-file.
The problem is the module "sqlserver" which I need to connect to sql server and get the zip file etc. Trying to overwrite it I get an error. I've tried to remove-module but it doesn't work as well.
The code:
try
{
[decimal]$lokaleVersion = 3.01 #
$deploymentVersion = 0
[string]$filetype = 'PS'
if($zipObject = Get-ZIPFile -lokaleAdminDBVersion $lokaleVersion -filetype $filetype -build 0)
{
$deploymentVersion = $zipObject.aktScriptVersion
if($deploymentVersion -gt $lokaleVersion)
{
Remove-Module -name sqlserver -Force
Unzip-File -zipObject $zipObject -zipname $filetype -modulePath $modulePath #error Access denied
$SubFolders = dir ($modulePath) | Where-Object {($_.PSIsContainer) -and ($_.Name -ne "sqlserver")} | ForEach-Object -Process {$_.FullName} -ErrorAction Stop
Import-Module -Name sqlserver -DisableNameChecking -Force
ForEach ($Folder in $SubFolders)
{
try
{
$a = (join-path -Path $modulePath -ChildPath ($folder.Split("\")[-1]) -Resolve) + "\" + "installer.ps1"
if(Test-Path ($a))
{
& $a
}
}
catch
{
Write-LogFile -Message $($Error[0].exception.message) -severity Fehler -modul $module
}
}
}
}
}
catch
{
if ($error[0].exception.message) {$message = $error[0].exception.message}
Write-LogFile -Message $message -severity Fehler -modul $module
}
It's important to overwrite the sub-folders (I'm updating the scripts) and the sqlserver-module should be updated regularly.
Thanks for your help.
I've done varied amounts of research into how to run a parameterised PS script from SSIS. I am having issues getting a parameterised script running. PS script is as follows, if I hard code the parameters into the script it behaves as expected:
Param ([string]$filepath,[string]$filename)
$Path = $filepath
$InputFile = (Join-Path $Path $filename)
$Reader = New-Object System.IO.StreamReader($InputFile)
While (($Line = $Reader.ReadLine()) -ne $null) {
If ($Line -match 'FILE\|([^\|]+)') {
$OutputFile = "$($matches[1]).txt"
}
Add-Content (Join-Path $Path $OutputFile) $Line
}
Running in SSIS execute process task, I am trying to build the Arguments command via an expression as follows:
"-ExecutionPolicy ByPass -File " + #[User::vPSScriptLocation] + " " + #[User::vFilePath]+ " "+ #[User::vFileName]
Evaluating the expression gives the following:
-ExecutionPolicy ByPass -File \\WorkDirectory\Script.ps1 \\transfer datafile.data
Upon execution, the task fails. The .ps1 is deleted from the work directory and SSIS gives the following error code:
Error: 0xC0029151 at Execute powershell script, Execute Process Task: In Executing "C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.exe" "-ExecutionPolicy ByPass -File \\WorkDirectory\Script.ps1 \\transfer datafile.data" at "", The process exit code was "-196608" while the expected was "0".
Looks like it's getting an empty string where it shouldn't? Any pointers appreciated.
OK so as it appears I could not call a UNC path to execute this using an Execute Process Task, I decided to execute this within a Script Task with a reference added to System.Management.Automation which allowed me to create a PowerShell instance. This is far from my ideal solution as I really wanted to call a .ps1 file, but looks like this is my only solution given I need to use a UNC path.
I build the PS script with my Dts variables and then executed it within the instance, which achieved the desired result:
public void Main()
{
string filepath = Dts.Variables["User::vUNCPath"].Value.ToString();
string filename = Dts.Variables["User::vFileName"].Value.ToString();
string searchterm = Dts.Variables["User::vSearchTerm"].Value.ToString();
bool fireAgain = true;
// Build powershell script
string script = "$Path = \""+filepath+"\";"+
"$InputFile = (Join-Path $Path \""+ filename+"\");" +
"$Reader = New-Object System.IO.StreamReader($InputFile);" +
"While (($Line = $Reader.ReadLine()) -ne $null) {" +
"If ($Line -match '"+searchterm+"') { "+
"$OutputFile = \"$($matches[1]).txt\"};" +
"Add-Content (Join-Path $Path $OutputFile) $Line}";
Dts.Events.FireInformation(0, "Info", "Powershell script built: " + script, String.Empty, 0, ref fireAgain);
try
{
// Create instance to run script
using (PowerShell psinstance = PowerShell.Create())
{
//Assign built script to this instance
psinstance.AddScript(script);
//Run powershell script
psinstance.Invoke();
}
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception ex)
{
Dts.Events.FireError(0, "Error", ex.Message, String.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
If you're running your script as a ps1-File with a param-block like this, your execution-call should name the parameters by their name:
"-ExecutionPolicy ByPass -File " + #[User::vPSScriptLocation] + " -filepath " + #[User::vFilePath]+ " -filename "+ #[User::vFileName]
This should do it, if you use a valid filepath and filename.
If it doesn't work, please try to write your script as a function and try it in a powershell-console. Your script as a function looks like this:
function SearchLines
{
Param (
[string]$filepath,
[string]$filename
)
$Path = $filepath
$InputFile = (Join-Path $Path $filename)
$Reader = New-Object System.IO.StreamReader($InputFile)
While (($Line = $Reader.ReadLine()) -ne $null) {
If ($Line -match 'FILE\|([^\|]+)') {
$OutputFile = "$($matches[1]).txt"
}
Add-Content (Join-Path $Path $OutputFile) $Line
}
}
Usage:
SearchLines -filepath "\\your\unc\path\here" -filename "filename.txt"
If this don't work for you, please let us know which error you got.
Thx.
UPDATE:
Based on your comments, i wrote your function new in the hope, it meets your requirements as close as possible. The function now looks like this:
function SearchLines
{
Param (
[string]$InputFile
)
$FileContent = Get-Content $InputFile
foreach($Line in $FileContent)
{
If ($Line -match 'FILE\|([^\|]+)')
{
$OutputFile = "$($matches[1]).txt"
}
Add-Content -Path $OutputFile -Value $Line
}
}
Usage:
SearchLines -InputFile c:\your\path\to\your\file.log
This function creates for every line in your given file a new file in the actual folder named what is written in the line. The Cmdlet Join-Path simply adds the two strings together, without any check for plausibility. That's why you can simply commit the full path to your file instead of the path and the file in separate parameters.
If you need the path of the inputfile to set it for your outputfiles, you can get it with these lines:
$tmpPath = Get-Childitem $InputFullPath
$Path = $tmpPath.Directory.FullName
Because you didn't explained what exactly this script should do, i hope you can use this to get what you wanted.
Greetings
I have a folder with 1 or more files like this:
bigfileA.txt
bigfileB.txt
bigfileC.txt
Each file contains 1 line and is delimited by '
For example, bigfileA.txt may contain abcdef'ghijklmnop'qrst
How can I use powershell so that when I run the .ps file it will automatically split all files in the specified directory into multiple files?
The output will look like this:
bigfileA1.txt --> abcdef
bigfileA2.txt --> ghijklmnop
bigfileA3.txt --> qrst
bigfileB1.txt --> uvw
bigfileB2.txt --> xyz
bigfileC1.txt --> ... and so on...
... and so on...
Can someone help? Thank you in advance!
The below script will go through a directory you choose and create a text file with the name of the base file + the current index (For example bigfileA + 1) and will have the delimited value inside.
$bigfiles = Get-ChildItem -Path 'C:\path\to\bigfiles\here'
ForEach ($path in $bigfiles)
{
$contents = Get-Content $path.FullName
ForEach ($line in $contents)
{
$splitItems = $line.split("'")
For ($i = 0; $i -lt $splitItems.count; $i++)
{
New-Item -Path "$($path.Directory)\$($path.BaseName)$i.txt" -ItemType File -Value $splitItems[$i]
}
}
}
EDIT: Re-read question, must have misinterpreted the first time. Updated code.
If you want the files to start at 1 instead of 0 change this line
New-Item -Path "$($path.Directory)\$($path.BaseName)$i.txt" -ItemType File -Value $splitItems[$i]
to this
New-Item -Path "$($path.Directory)\$($path.BaseName)$($i+1).txt" -ItemType File -Value $splitItems[$i]
We're simply changing the $i to $($i+1)
Functional Edit
Has not been tested and was put together quickly because i'm at work but it's at least a start :)
function Split-BigFiles
{
[CmdletBinding(DefaultParameterSetName='All',
SupportsShouldProcess=$false,
PositionalBinding=$false)]
Param
(
# Paths to bigfiles
[Parameter(Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$false,
ValueFromRemainingArguments=$false,
Position=0,
ParameterSetName='All')]
[ValidateScript({Test-Path $_ -PathType Container})]
[ValidateNotNullOrEmpty()]
[String[]]
$Path
)
Begin
{
Write-Verbose "Starting Function Split-BigFiles"
}
Process
{
ForEach($folder in $Path)
{
Try
{
$bigfiles = Get-ChildItem -Path $folder -ErrorAction Stop
}
Catch
{
Write-Warning "Oh no i couldn't get the folder! This is the error i got $($_.Exception.Message)"
}
if ($bigfiles)
{
ForEach ($path in $bigfiles)
{
$contents = Get-Content $path.FullName
ForEach ($line in $contents)
{
$splitItems = $line.split("'")
For ($i = 0; $i -lt $splitItems.count; $i++)
{
New-Item -Path "$($path.Directory)\$($path.BaseName)$i.txt" -ItemType File -Value $splitItems[$i]
}
}
}
}
}
}
End
{
Write-Verbose "Exiting Function Split-BigFiles"
}
}
So my larger project is to come up with a way of finding UNC path names that are too long, and once I have that information, use them as mapped drives so that I can run Get-Child information below that point.
I have the following code which gets me a Write of the folders that match that criteria, and display the UNC path to me, and I would like to add that information to an array that can be called back
Here is the code I have at the moment:
Get-ChildItem "\\Server\Share" -recurse -ErrorAction SilentlyContinue -ErrorVariable err
foreach ($errorRecord in $err)
{
if ($errorRecord.Exception -is [System.IO.PathTooLongException])
{
Write-Warning ($errorRecord.TargetObject)
$ErrorArray = $errorRecord
}
else
{
Write-Error -ErrorRecord $errorRecord
}
}
Out-File C:\ErrorArray.txt
Being new to PS, can anyone please point me in the right direction please?
Add a variable $results to hold errors you want to capture and pipe that out to a file. As well as that grab the string with error message - $errorRecord.TargetObject - rather than the entire error object.
$results = #()
Get-ChildItem "\\Server\Share" -recurse -ErrorAction SilentlyContinue -ErrorVariable err
foreach ($errorRecord in $err)
{
if ($errorRecord.Exception -is [System.IO.PathTooLongException])
{
Write-Warning ($errorRecord.TargetObject)
$results += ,$errorRecord.TargetObject
}
else
{
Write-Error -ErrorRecord $errorRecord
}
}
$results | Out-File C:\temp\ErrorArray.txt