Записи с меткой «SharePoint development»

0-2022-11-30_205613    1-2022-11-30_205206

Результат:

2-2022-11-30_205533

Скрипт пробегается по всем записям начиная с меньшего ID. Мне так и не удалось ‘скормить’ caml-запрос команде Get-PnPListItem, хотя параметр -Query у этой команды раньше там был.

Поэтому добавил маленький блок-настройку на 38-ой строке, где можно добавить своё условие. К примеру: вам нужно выгрузить не все вложения, а только для записей из Москвы или регионов. Тогда можно заменить условие ниже:

$condition = $true

на например что-то такое:

$condition = ($listItem.City -eq «Moscow») -or ($listItem.City -eq «Moscow Region»)

# или к примеру чтобы выгрузить аттачменты только начиная с какого-то элемента/времени:
$condition = ($listItem.ID -gt 7000)

ну и так далее.

Скрипт поддерживает threshold > 5000 и также работает с большими списками.

Код:

$url="https://portal.sharepoint.com/sites/web/"

# здесь может быть diplay name или guid 
$listName="Listname"  

# кроме системных полей
$includeHiddenField = $False
$includeReadonlyField = $False

# по умолчанию 'C:\Users\Administrator'
$saveDir = (Resolve-path ".\")  

 
function ExportList  
{  

    # все поля кроме системных (возможно какое-то из полей будет удобно использовать в кач-ве названия папки)
    $listFields = Get-PnPField -List $listName |? { $_.Hidden -eq $includeHiddenField -AND $_.ReadOnlyField -eq $includeReadonlyField} | Select -ExpandProperty internalname

    $count = 0
    try  
    {  
        md .\$listName -Force
        md ".\$($listName)\Attachments" -Force

        
        $listItems=(Get-PnPListItem -List $listName -Fields $listFields -PageSize 1000).FieldValues
        
        foreach($listItem in $listItems)  
        {   
            $count = $count+1
            Write-Progress -Activity "Exporting" -Status "$($count/$listItems.Count*100)% Complete:" -PercentComplete $($count/$listItems.Count*100)

            $listItem.GetEnumerator() | Where-Object { $_.Key -in $listFields }| ForEach-Object{ 
                    
                    if($_.Key -eq "Attachments" -And $_.Value -eq "TRUE"){
                        
                        $condition = $true
                        #$condition = ($listItem.City -eq "Moscow") -or ($listItem.City -eq "Moscow Region")
                        #$condition = ($listItem.ID -gt 7000)
                        

                        if ( $condition )
                        {
                            Write-Output "Downloading file.."

                            # папка в данном примере содержит ID и Title 
                            $path = "$($listItem.ID)" + " - " + "$($listItem["Title"])"

                            # на практике записи SharePoint содержат спецсимволы или пробелы в конце, которые не позволят создать папку
                            # частично можно обойти так:
                            $path = $path -replace "[$([RegEx]::Escape([string][IO.Path]::GetInvalidFileNameChars()))]+"," "
                            $path = $path.Trim()
                            Write-Host $path

                        
                            md ".\$($listName)\Attachments\$($path)" -Force
                        
                            $item = Get-PnPListItem -List $listName -Id $($listItem.ID)
                        
                            $attachments = ForEach-Object{Get-PnPProperty -ClientObject $item -Property "AttachmentFiles"}
                            
                            $attachments | ForEach-Object {
                            
                                Get-PnPFile -Url $_.ServerRelativeUrl -FileName $_.FileName -Path ".\$($listName)\Attachments\$($path)"  -AsFile -Force
                            
                            } 
                        }
                    }
                }
                 
            Write-Host $count
        }  
  
     }  
     catch [Exception]  
     {  
        $ErrorMessage = $_.Exception.Message         
        Write-Host "Error: $ErrorMessage" -ForegroundColor Red          
     }  
}  
 

Connect-PnPOnline -Url $Url -UseWebLogin
 
ExportList  
 
Disconnect-PnPOnline
Реклама

reSP — great Resharper plugin from SubPoint Solutions.

Makes Your SharePoint solutions code more stable and robust:
http://subpointsolutions.com/resp/

Несмотря на то, что давно есть ITIL, бизнес и IT разговаривают на разных языках. Это иллюстрируется диалогом на одной из презентаций какого-то мега-супер-пупер SharePoint документооборота, когда на вопрос из зала

«Так а как в итоге мне сделать отчёт вот по вот этим вот карточкам, чтоб за месяц?..»

докладчик отвечает что

«Для отчётов у нас есть ‘БиАй-чик’, и кстати мы вынесли его на отдельные сервера. У нас распределённая ферма..»

Топология развёрнутой фермы интересует конечных пользователей в зале примерно также, как зайца интересует луна, а вот отчёт..

Но дело не только в этом. Недавно мне попался пост автора Bjørn Furuknap, я переведу его здесь так как на мой взгляд он является must-read для людей, которые хотели бы внедрить SharePoint, или просто посмотреть что это и как это может помочь их бизнесу, либо чувствуют что хотелось бы улучшить то что есть, но ещё сами не понимают как(и это imho вполне нормально)

В оригинале пост называется “SharePoint and Why It Always Depends”, но для русской аудитории я позволил себе немного переиначить название. Сам текст рассчитан на англоязычного читателя, но общий смысл будет донесён.

Как правильно ставить задачи SharePoint –разработчику

Когда вы задаёте SharePoint-консультанту вопрос, велики шансы что вы получите ответ “В зависимости от ситуации..”. Клиента подчас такой ответ разочаровывает, и мне кажется что в этом месте имеет смысл уточнить — почему же многое в SharePoint-е действительно — «В зависимости от ситуации..»

И раз уж быть честным, то на самом деле по большей части это ваша вина, как заказчика. Я здесь чтобы помочь вам разобраться, хотя мне тоже немного жаль что вы не услышите привычное «Клиент всегда прав!». Ну – по крайней мере в этом абзаце точно не услышите..

Реальность заключается в том, что вы делаете свою работу, а мы, как SharePoint разработчики – должны иметь возможность делать свою. Единственная вещь которую действительно надо выстроить – это понять каким образом мы можем быть вам полезны.

А что же для этого нужно? Ну, как вам сказать..

В зависимости от ситуации!..

Задавая неверный вопрос

Задавая неверные вопросы, вы гарантированно не получите нужный ответ. Так как же задать правильный вопрос и не попасть во всё сдувающую турбину однотипных «в зависимости от ситуации»?

Дело в том, что SharePoint – чрезвычайно массивный продукт, и в нём существует великое множество мелочей, без учёта которых невозможно выдать клиенту действительно хороший ответ. Эти мелочи — напрямую зависят от вопроса, поэтому чем более точно поставлен вопрос, и чем больше информации вы дадите о вашей текущей ситуации — тем больше шансов на то что вы получите ответ, который потом позволит вам выжать из SharePoint максимальную выгоду.

Я осознаю что вы, как клиент, вполне можете не знать о факторах, которые влияют на возможность дать вам хороший ответ. И это нормально; даже многие SharePoint-профессионалы не могут сразу определить, что будет иметь влияние именно в вашей ситуации. Вот почему когда вы спрашиваете специалиста по SharePoint — профессионал скорее всего задаст вам несколько смежных вопросов, которые помогут ему понять – что именно вы хотите получить в итоге.

В этом заключается ключ в понимании как задавать правильный вопрос. Спрашивая, чаще всего имеет смысл сфокусироваться на том, чего вы хотите достичь, нежели на том как сделать что-то определённым образом. Это проще понять на примере.

"А как мне сделать X в SharePoint?"

Вы могли бы подумать, что задаёте вполне конкретный вопрос, спрашивая к примеру – «Как мне добавить пользователей на сайт-коллекцию SharePoint?». Мысля с колокольни разработчика, я в свою очередь могу подумать о минимум трёх разных способах добавления пользователей на сайт-коллекцию SharePoint, и каждый имеет право на жизнь в определённом сценарии. Добавляете ли вы юзеров через веб-интерфейс, или в вашем случае нужно написать код чтобы делать это через веб-часть; а возможно права раздаются пользователям в обработчике событий?

Скорее всего, если вы не разработчик SharePoint -то наиболее вероятно что вы предполагаете использовать веб-интерфейс. Это хорошо, но тогда в этом случае берут ответвления новые вопросы, зависящие от того, как именно устроена ваша SharePoint security. Возможно в вашем решении пользователи получают доступ не напрямую, а через группы Active Directory, в таком случае вообще не затрагивая SharePoint.

Даже убедившись, что вы просто хотите дать пользователю доступ на сайт, и отметя прочие, нестандартные сценарии – всё равно нужно знать – какой Уровень разрешений вы собираетесь назначить пользователю, выдавая ему доступ. Он может варьироваться от уровня администратора сайт-коллекции, до прав читателя без возможностей редактирования и изменения чего-либо в этой сайт-коллекции, а может до прав только на определённый список — или вообще: просто иметь возможность скачать единственный документ в некоем списке вашей сайт-коллекции. И это приводит нас к разговору о том, какой набор уровней разрешений использовать в вашей фирме..

Вышеописанный пример применим и ко всем прочим вопросам из категории «А как мне сделать X в SharePoint». Теперь вы примерно представляете себе, как на первый взгляд легко решаемая задача -становится практически невозможной без получения дополнительных сведений конкретно о вашем случае и том, что же вам в итоге нужно получить на выхлопе.

Разновидность, подвид от вопроса выше — «А как мне наилучшим способом реализовать X в SharePoint?» – ещё более труден для ответа и является даже более вероятным кандидатом на получение в ответ “В зависимости от ситуации…”. В отсутствие соответствующих исследований вашей ситуации, «лучшесть», «хорошесть» — да или просто вообще возможность реализовать что-либо — в данном случае будет зависеть от слишком многих факторов-мелочей, на которые требуется ответ.

Чего вы в итоге хотите?

Вместо того, чтобы спрашивать как сделать то или это наилучшим образом – сфокусируйтесь на том чего вы в итоге хотите добиться. Для примера выше это может формулироваться например в таких строках: «у нас есть сотрудник из отдела бухгалтерии, и ему нужно ознакомиться с несколькими отчётами на нашем SharePoint сайте. У нас в компании есть настроенные группы Active Directory, но в данном случае нам нужно только единоразово выдать им доступ, да и прямого доступа изменять состав групп на домен-контроллере у меня нет. Как мне убедиться что бухгалтера получат эти отчёты?»

Даже с таким, довольно подробным объяснением, всё ещё возможен ответ «В зависимости от». Вдруг всё-таки лучшим решением для вас — будет выкачать эти отчёты и переслать их бухгалтерам по e-mail, на случай если, к примеру, вас сильно беспокоит что они получат «лишний» доступ к неким остальным частям сайта. Так или иначе – с дополнительной информацией уже намного проще дать вам нормальное предложение, которое в итоге реализует то чего вы хотите достичь. А это в свою очередь увеличивает ваши шансы получить от SharePoint больше.

По факту, это общий совет который можно дать когда речь заходит о SharePoint. Фокусируйтесь на том, чего вы хотите, нежели на том, как это реализовать. И если второе здесь –только для SharePoint-разработчика, то первое – только для вас.

.b

ссылка на оригинал

iLoveSharepoint Power Webpart для Sharepoint 2010 позволяет вставлять скрипты на Powershell прямо в страницы портала.

Так как за powershell-ом лежит практически весь .NET(и не только), то это позволяет создавать интересные решения, без открытия студии и развёртывания wsp.

Для иллюстрации создадим какую-нибудь функцию на Powershell, к примеру будем приветствовать юзера в зависимости от времени суток. Имя текущего пользователя выведем в дружественном формате.

# подключим SharePoint безопасным образом
$sharePointSnapin = Get-PSSnapin | Where-Object { $_.Name -eq  "Microsoft.SharePoint.PowerShell"}
if($sharePointSnapin -eq $null)
{
    Add-PSSnapin Microsoft.SharePoint.PowerShell    
}


# поздороваемся с пользователем, в зависимости от времени суток
Function GetGreeting()
{
    # текущее время
    $actualtime = (Get-Date).TimeOfDay;

    # выберем интервал
    $evening = New-TimeSpan -Hours 17 -Minutes 30 -Seconds 0
    $morning = New-TimeSpan -Hours 8 -Minutes 0 -Seconds 0
    $dinner = New-TimeSpan -Hours 11 -Minutes 0 -Seconds 0
    $night = New-TimeSpan -Hours 22 -Minutes 0 -Seconds 0
    
    if ($actualtime -ge $morning -and $actualtime -le $dinner)
    {
        return "Доброе утро";
    }
    if ($actualtime -ge $dinner -and $actualtime -le $evening)
    {
        return "Добрый день";
    }
    if ($actualtime -ge $evening -and $actualtime -le  $night)
    {
        return "Добрый вечер";
    }
    if ($actualtime -ge  $night -or $actualtime -le  $morning)
    {   
	    # дикий случай, но допустим
        return "Доброй ночи :)";
    }
}


# для получения Display Name можно каждый раз делать запрос к домен-контроллеру, 
# но так как формат имени в домене имеет стандартный вид "Домен\Имя.Фамилия",
# то выведем friendly-имя прямо тут же в вебчасти
Function GetDisplayName($name)
{
    if($name -match "\\")
    {
        $name = $name.remove(0, $name.LastIndexOf('\')+1);
    }
    if($name -match ".")
    {
        $name = $name.replace("."," ");
    }
           
    return $name
}

# соберём всё вместе
$hello = (GetGreeting)+ ", " + (GetDisplayName -name ([Environment]::UserName))


# вывод html
function Render($writer)
{
    $writer.Write("<h1>$hello</h1>")
}

Результат работы такого кода:

image

Таким образом мы получаем динамическое поведение в Sharepoint, но без создания «полновесного» решения с кодом

Есть система багтреккинга, сделанная на Sharepoint с использованием Infopath-форм.

Формы имеют несколько копий и в зависимости от принадлежности сотрудника в AD, ему подставляется своя копия и люди из разных отделов могут редактировать только свои поля:

image

Задача:

После экспорта узла из вида пропало поле «Статуса». То есть на форме оно есть, а в колонках видов и настройках списка уже нет.

Решение:

— Переопубликовать форму в Infopath Designer(колонка должна появиться, но без значений).

— Обновить все элементы списка, чтобы значения появились в видах SharePoint.

Программно это можно сделать например так

  using (SPSite site = new SPSite("http://server/webName "))
 using (SPWeb web = site.OpenWeb())
 {
 SPList list = web.GetList("http://server/webname/libName/");
 foreach (SPListItem item in list.Items)
 {
 try
 {
 Console.Write("Updating " + item.ID.ToString());
 item.SystemUpdate();
 Console.WriteLine(".. Ok.");
 }
 catch (Exception ex)
 {
 Console.WriteLine(ex.ToString());
 }
 }
 } 

или через Powershell:

$web = Get-SPWeb -identity "http://server/webName"
 
$list = $web.Lists["listName"] 

$list.Items | ForEach-Object { Write-Host "Updating " $_.Name; $_.SystemUpdate(); }

$web.Dispose()

p.s.: при этом пользовательские виды с участием этих “пропавших и возвращённых” полей возможно прийдётся пересоздать