I am facing an issue using the Task Scheduler to run a Sharepoint Powershell script.
I'm using the following in the Task Scheduler :
-Command "& 'C:\Users\crpmcr\Desktop\Upload\Script.ps1'"
This is the resume of my script :
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
New-Item "[PATH]" -type file
$stream = [System.IO.StreamWriter] "[PATH]"
$stream.WriteLine("Message Example")
Try{
$web = Get-SPWeb "[WebApplicationUrl]"
}
Catch{
$stream.WriteLine("Error")
}
$stream.close()
If i remove the line in the try, i get the Message Example line in my new file. But it seems that the line in the try does make everything break. My file is created but it's empty. Even if some text has been added before. Also the rest of my script using the web is not working obviously.
Any idea about what my problem could be ?
Thanks!
If you are running PowerShell from
C:\Windows\SysWOW64\WindowsPowerShell\v1.0
Try changing it to
C:\Windows\System32\WindowsPowerShell\v1.0
And see if that makes any difference.
Solution found. My script was creating a file for logs and when i clicked in it it was empty. So i thought there was an issue but in fact it's because the line GetSP-web take severals seconds on my server. so it blocks the writing while it's looking for the web. 10 seconds later my file had the lines added. Obviously i was too fast and had to wait longer to see the result.
Related
I may be going about this the wrong/more difficult way. I am open to suggestions.
I am running NTLite v2.3.8.8920 [HOME] ((c) NTlitesoft d.o.o) to create unattended Windows 10 discs. After years of doing unattended discs and realizing the ever expanding size of the disc, (Latest disc was 32.73GB!), I found WinGet, the absolutely amazing repository, and have even gone as far as to create my own installer!
The issue for today is: how do I access WinGet during an unattended installation? I have compiled a list of applications that I use frequently; most that I have been hard coding to the disc and thus this incredible size; and I would love to be able to run this script post-setup and save the time and space. Here is my code:
#The first batch here is a function I created for notification purposes. Not sure how to do timed popups in Powershell yet.
#Get Words
function GW($myinput){
$WS = New-Object -ComObject "Wscript.Shell"
$ws.popup($myinput,3,'TK Installer',64)|SET-CLIPBOARD}
SET-CLIPBOARD to offload the popup response code. Need to find a better output or a way to prevent printing this response.
function install-myapps(){
Clear-Host
#Variable to hold the application list
$myapps = (
'Microsoft.PowerShell',
'Microsoft-Windows.Terminal',
'Microsoft.DotNet.SDK.3_1',
'Microsoft.DotNet.SDK.5',
'Microsoft.DotNet.SDK.6',
'Microsoft.MSIXCore',
'Microsoft.msmpisdk',
'Microsoft.ADKPEAddon',
'Microsoft.WebDeploy',
'9N5LW3JBCXKF',
'Nlitesoft.NTLite',
'Libretro.RetroArch',
'Notepad++.Notepad++',
'CodecGuide.K-LiteCodecPack.Full',
'Foxit.FoxitReader',
'7zip.7zip',
'OBSProject.OBSStudio',
'XnSoft.XnConvert',
'XnView.Classic',
'XnSoft.XnViewMP',
'corel.winzip',
'XP8K0J757HHRDW')
#Parser
ForEach-Object($aa in $myapps.Split(',')){
#Notification
GW "Installing $aa`nPlease wait..."
#Installer
WinGet install $aa --silent --accept-package-agreements --accept-source-agreements --force}
}
This code works perfectly in both command line and exe format; the latter using PS2EXE or IExpress. I just cannot figure out how to instantiate it post-setup from the unattended Win1021H2 side. Any help or insight would be greatly appreciated!
I was unable to figure out the process for this so I worked it around differently.
Below is how I fixed this situation:
# The first section opens and names function and
# declares variable $Hopeful applied to the full URI for the application we are installing
# !Considering using get-input but for now we will just use a replaceable variable!
# The second section begins the downloading and saving process
# Begins by separating the application from the URI assuming the format is as www.domain.com/application.exe
# Note now that the variable $JustApp will pull the just the last portion of the URI which is the application name
# Also, we'll make sure that what we're trying to do is possible by checking the extension of the last object
# Because wget needs 2 things; the URI and a place for the download to go; I am creating a directory to put these
# downloads in. Thus, $MyDir\$JustApp is now the default file point.
cls
Clear-Host
$MyDir = "d:\TKDI\"
# Create directory
if($mydir|Test-Path){
"My Directory Already Exists!"
}else{
md $MyDir -Force
}
# Section 1
Function TKDI($Hopeful,$MyArgs){
$_|select
# Section 2
$JustApp = $hopeful -split('/')|select -last 1
if($justapp -match "exe")
{
switch($MyArgs)
{
inno{$x ='/sp- /silent /forcecloseapplications /restartapplications /norestart'}
S{$x ='/S'}
silent{$x ='/silent'}
quiet{$x ='/quiet'}
passive{$x ='-passive'}
default{$x =$myargs}
un{$x ='-uninstall'}
$null{$x='/?'}
}
cls
echo "Processing $justapp"
if(Test-Path $mydir$justapp -PathType Leaf){echo 'File Downloaded Already!'}else{wget -Uri $hopeful -OutFile $MyDir$justapp}
$noteit = 'Installing $justapp in 5 seconds...'
$x=6;while($x-- -ge 1){cls;Write-host $x;sleep 1}
start -verb runas -wait -FilePath $mydir$justapp -ArgumentList $x
}elseif($justapp -match "msi")
{
cls
echo "You're file will be downloaded and installed!"
wget -Uri $hopeful -OutFile $MyDir$justapp
start -wait -Verb runas msiexec.exe -ArgumentList "-i $mydir$justapp /passive /norestart"
}else{
echo "This URI does not result in an application!"
}
}
tkdi www.example.com/index.exe inno #Installs beautifully```
I have a code that downloads a file from SharePoint, edits it, uploads it back to SharePoint and finally sends a confirmation email. I have functions for each of the tasks. The code works fine.
However, I want to add error exception for a condition when if the file is open in SharePoint by some user, show error message and exit code. The issue I am experiencing is the code continues to run even if there is an exception. In the below code, the sendMail function is called even when the getSharePointFile function fails.
I have tried $ErrorActionPreference = "Stop" but with that, the catch block is not executed and my custom error MessageBox is not displayed. Thanks in advance.
Here is the relevant code:
function getSharePointFile {
Connect-PnPOnline $SharepointURL -UseWebLogin
Get-PnPFile -Url $fileRelativeURL -Path $localFilePath -FileName $fileName -AsFile -Force
}
function runCatch {
$showMessage = [System.Windows.Forms.MessageBox]::Show($_)
exit
}
try {getSharePointFile}
catch{runCatch}
try {updateAuditResults}
catch{runCatch}
try {uploadToSharePoint}
catch{runCatch}
try {sendMail}
catch{runCatch}
Two issues:
First, you have four independent try catch blocks, and an error handled in one has no impact on the others.
Try something like this:
try {
getSharePointFile
updateAuditResults
uploadToSharePoint
sendMail
}
catch{runCatch}
The first line to generate an error will end the batch of commands and jump to the catch block. The rest of the batch will be skipped.
The second issue you might run into is not all PowerShell cmdlets return errors when they fail. You will need to test yours to verify. Some will just display error text and continue.
More info here: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally
As #Mike Smith said, with the code you provided, it seems better to merge your function calls inside one try catch block.
Depending on your PowerShell version, you also need to add -ErrorAction Stop parameter to trap errors into the catch block (add it for the cmdlets, not the function call)
function getSharePointFile {
Connect-PnPOnline $SharepointURL -UseWebLogin -ErrorAction Stop
Get-PnPFile -Url $fileRelativeURL -Path $localFilePath -FileName $fileName -AsFile -Force -ErrorAction Stop
}
I was trying to migrate my batch script to powershell.
I have tried writing the script and run it from powershell ise.
$sites = #("abc","xyz","pqr")
foreach ($site in $sites)
{
msdeploy -verb:sync -verbose -source:runcommand -dest:runcommand="$env:windir\system32\inetsrv\appcmd stop site /site.name":$site
}
When I run the command(msdeploy) it runs perfect from command prompt.
I get the following error (attached):
Error capture
I would appreciate if someone can help me on this. Thanks in advance.
You need to use Invoke-Expression which will allow you to execute a string as a command. Store your command as a string and pass it to Invoke-Expression as a parameter.
$sites = #("abc","xyz","pqr")
$commandPrefix = 'msdeploy -verb:sync -verbose -source:runcommand -dest:runcommand="$env:windir\system32\inetsrv\appcmd stop site /site.name"'
foreach ($site in $sites)
{
$command = $commandPrefix ":" $site
Invoke-Expression $command
}
After so much of struggle I figured it out, and resolved the issue.
foreach($site in $sites){
msdeploy -verb:sync -verbose -source:runcommand -dest:runcommand=`"$env:windir\system32\inetsrv\appcmd stop site /site.name`":"$site",computername="$serverName",username="$user",password="$passCode"
}
It was just a escape character that helped me to run the script("`").
I hope it helps someone without pulling their hair.
You can also try using the recycleApp provider:
msdeploy -verb:sync -source:recycleApp -dest:recycleApp="MySite",recycleMode="StopAppPool"
//deploy and sync content
msdeploy -verb:sync -source:recycleApp -dest:recycleApp="MySite",recycleMode="StartAppPool"
I am in a situation, when I would like to queue a few mailboxes to export (I don't want them to be processed at the same time) to PST files. I know, how to export them it with a command get-mailboxexportrequest, but when I do it, they almost instantly begin. Can I somehow queue another mailbox, so it would automatically start, when the previous one is completed?
I would do the following:
Build a powershell script which is checking if there is a running export happening (via Get-MailboxExportRequest) if that isn´t the case start to export x mailfiles you specify inside a CSV file
Use the Windows taskmanager on your Exchange Server to trigger that script and define a timeframe here how often and when your script should run
Once the powershell script runs, it should remove the exported mailfile from the CSV file and then quit
The next run from the powershell script via the taskmanager will then check if the current job is still ongoing, if it is, it should quit until its time to pick up the next entry from your list
Update:
As a starting point something like the following should be fine (untested but should give you a starting point):
# Get current Export Requests
$ExportStats = Get-MailboxExportRequest
#Check if there are completed questes
If ($ExportStats.Status -eq "Completed")
{
Write-Host "Export done"
Get-MailboxExportRequest -Status Completed -Name "$ObjectName-Export" | Remove-MailboxExportRequest -Confirm:$false
#Disable-Mailbox -identity "AD\$ObjectName"
# Create a new CSV file, which isn´t including the current export name we just marked as finish via above's section.
# CODE MISSING HERE!
# Now import our CSV list and proceed it
Import-CSV <Filepath of CSV file(\\server\folder\file.csv)> | ForEach-Object {
# Perform the export
New-MailboxExportRequest -Mailbox $_.MailboxAlias -FilePath $_.PSTpath
New-MailboxExportRequest -Mailbox $_.MailboxAlias -FilePath $_.ArchivePath
# Once done exit here, this will ensure we proceed only the first entry
Exit
}
}
elseif ($ExportStats.Status -eq "InProgress")
{
Write-Host "Export still ongoing"
}
I'm running the following command from within a Microsoft System Centre Orchestrator PowerShell activity:
Install-WindowsFeature -ConfigurationFilePath C:\DeploymentConfigTemplate.xml -ComputerName ServerXYZ
the command isn't doing what it's supposed to do, and I want to be able to return if the command was successful or not, and any error message if possible. Ignore the fact it's running in Orchestrator, as I'm more concerned about the PowerShell question. When I run the command from ISE it does what it's supposed to do, that's why I want to see what is returned from PowerShell.
Thanks.
It's hard to know what may be happening without more context. The following will record any errors encountered in an xml file that you can import later with import-clixml:
Install-WindowsFeature -ConfigurationFilePath C:\DeploymentConfigTemplate.xml -ComputerName ServerXYZ
IF (!($?)) {
$error[0] | export-clixml C:\myerror.xml
}
This solves my problem:
$Result = Install-WindowsFeature -Name SNMP-Service -IncludeAllSubFeature -IncludeManagementTools
Write-Host $Result.ExitCode