2012年11月26日 星期一

Develop Google Maps API v3 Map Pages with ASP.NET AJAX


  • 前言:Google Maps API 提供服務以來,由於容易開發、API功能多更新快並且又穩定,只要不踩到一些地雷,就不會收錢,所以一直是地圖開發者喜歡用的工具API。這一篇是要介紹,從資料庫取得點位資料套疊到地圖上。我使用的工具是 ASP.Net 使用 Google Map API v3 ,並且用AJAX,是因為如果用標準的asp.net button,會submit/postback 回 server,如果使用者在submit之前就做了一些地圖操作(放大、移動..),就會因為submit to server 會回到初始畫面,這樣的操作模式是滿令人不悅的,所以才需要AJAX方式來處理使用者對地圖的操作。
  • 網頁功能:取得使用者目前座標,繪製地點與精確度的範圍。並根據使用者點選的圖層類型,帶入對應的點位。
  • 瀏覽器限制:因為有用到HTML5,IE8,9確定不行,用 Chrome Ok, IPhone Safari OK
  • 使用元件:
    • Google Map API V3 :必要
    • Visual Studio 2012:必要
    • JQuery mobile:非必要,放著只為了可以在行動裝置上看。
    • HTML5:必要,為了取得目前座標。所以..那個 IE
  • 網頁主要分成 3 區 
    • (1)地圖區:顯示地圖
    • (2) ASP.Net button 區:負責從資料庫取得資料,並呈現在地圖
    • (3) JS Button區:主要是 javascript button,是操作google map的功能,如"取得目前位置"、"清除地圖" 這類的功能

  • 以下列出比較重要的程式片段,完整的程式請到網頁最下方再去下載。
  • HTML Head區:需要注意的是 style 那一區,因為 Google Map DIV必須指定大小,所以指定在Head裡面。其他就是引用 jquery 與 google map api v3
<head>
    <title>Google Maps API v3 and ASP.Net AJAX</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1" /> 
    <style type="text/css">
      html { height: 100% }
      body { height: 100%; margin: 0px; padding: 0px }
      #map_canvas { height: 100% }
    </style>
 <link rel="stylesheet" href="/css/jquery.mobile-1.2.0.min.css" />
    <script src="/js/jquery-1.8.2.min.js"></script>
    <script src="/js/jquery.mobile-1.2.0.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>

  • 再下來就是控制google maps div 的區域,首先是global的變數
        //Global variables
        var map;            //地圖
        var marker;         //地圖上的點
        var infowindow;     //點上面跳出的視窗
        var overlays = [];  //目前地圖上所有套疊的圖層
        var mapcenter = new google.maps.LatLng(25.228664, 121.750202);  //預設的地圖中心

  • 地圖初始化的function,等下會在body onload呼叫。裡面的詳細API 請參考Google 文件。在初始化完成後,呼叫 取得目前座標的function: getLocation。
        function initialize() {
            var mapOptions = {
                zoom: 6,
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                center: mapcenter,
                mapTypeControl: true,
                mapTypeControlOptions:
                {
                    style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
                    poistion: google.maps.ControlPosition.TOP_RIGHT,
                    mapTypeIds: [google.maps.MapTypeId.ROADMAP,
                    google.maps.MapTypeId.TERRAIN,
                    google.maps.MapTypeId.HYBRID,
                    google.maps.MapTypeId.SATELLITE]
                },
                navigationControl: true,
                navigationControlOptions:
                {
                    style: google.maps.NavigationControlStyle.ZOOM_PAN
                },
                scaleControl: true,
                disableDoubleClickZoom: false,
                streetViewControl: true,
                draggableCursor: 'move'
            };

            infowindow = null;
            infowindow = new google.maps.InfoWindow({
                content: "info window content"
            });

            map = new google.maps.Map(document.getElementById('map_canvas'),
            mapOptions);
            
            //取得使用者目前座標
            getLocation();
        }

  • 取得目前位置化的function:使用HTML5的方式取得座標(點)與精確度(圓圈),並繪製到地圖上。
        //
        //取得目前位置
        //
        function getLocation() {
            var x = document.getElementById("Message");
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(showPosition);
                //如果要持續取得,用watchPosition
//navigator.geolocation.watchPosition(showPosition); } else { x.innerHTML = "Geolocation is not supported by this browser."; } } function showPosition(position) { var x = document.getElementById("Message"); //x.innerHTML = "Latitude: " + position.coords.latitude + " Longitude: " + position.coords.longitude + " Accuracy" + position.coords.accuracy; var newMapCenter = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); map.setCenter(newMapCenter); //以marker方式出現 setMarker(newMapCenter, "My Current Location" + " Accuracy is :" + position.coords.accuracy); //以圓形出現 if (position.coords.accuracy != null) { DrawCircle(newMapCenter, position.coords.accuracy); if (position.coords.accuracy < 1000) { map.setZoom(14); } } else { DrawCircle(newMapCenter, 100); } }
  • 繪圖用的function,繪製圓形、繪製單一點座標與視窗(infowindow)訊息
        //繪製圓形
        function DrawCircle(center,rad) {
            var draw_circle;
            draw_circle = new google.maps.Circle({
                center: center,
                radius: rad,
                strokeColor: "#FF0000",
                strokeOpacity: 0.8,
                strokeWeight: 2,
                fillColor: "#FFFF00",
                fillOpacity: 0.35,
                map: map
            });
            overlays.push(draw_circle);
        }

        //繪製單一點座標
        function setMarker(singleCoord,infoWindowContent) {
            marker = new google.maps.Marker({
                map: map,
                draggable: true,
                animation: google.maps.Animation.DROP,
                position: singleCoord
            });

            google.maps.event.addListener(marker, 'click', function () {
                infowindow.setContent(infoWindowContent);
                infowindow.open(map, this);
            });

            //
            overlays.push(marker);
        }

        //產生彈跳效果
        function toggleBounce() {
            if (marker.getAnimation() != null) {
                marker.setAnimation(null);
            } else {
                marker.setAnimation(google.maps.Animation.BOUNCE);
            }
        }
  • 繪製多個點,提供給asp.net程式呼叫。Javascript Array的格式是['Mount Evans', 59.32522, 18.17002, 4, 'This is Mount Evans.'];,C#要繪製多點的時候,就是去準備出這個多筆陣列,再交給 setMarkers 去繪製。
        function setMarkers(markers) {
            for (var i = 0; i < markers.length; i++) {
                var sites = markers[i];
                var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
                var marker = new google.maps.Marker({
                    position: siteLatLng,
                    map: map,
                    title: sites[0],
                    zIndex: sites[3],
                    html: sites[4]
                });

                var contentString = "info window content";

                google.maps.event.addListener(marker, "click", function () {
                    infowindow.setContent(this.html);
                    infowindow.open(map, this);

                    if (marker.getAnimation() != null) {
                        marker.setAnimation(null);
                    } else {
                        marker.setAnimation(google.maps.Animation.BOUNCE);
                    }
                });

                //
                overlays.push(marker);
            }
        }
  • 清除全部繪製的圖層
        function clearMarkers() {
            while (overlays[0]) {
                overlays.pop().setMap(null);
            }
        }
  • 另外在.ASPX網頁設計上,只有ASPX的Controls(Button1~4,顯示A~D類的圖層資料),放在UpdatedPanel裡面。Google Map DIV 更要在Form 以外才能正常顯示。控制地圖的HTML Button(Button 6,7)則是單純的HTML button就可以
<div id="Message"></div>
    <div id="map_canvas" style="width:100%; height:80%"></div>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                AJAX Button:<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="All" />
                <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="A" />
                <asp:Button ID="Button3" runat="server" OnClick="Button3_Click" Text="B" />
                <asp:Button ID="Button4" runat="server" OnClick="Button4_Click" Text="C" />
                <asp:Label ID="Label1" runat="server" Visible="False"></asp:Label>
                <br />
                <asp:Label ID="lbErr" runat="server" Visible="False"></asp:Label>
                <br />
            </ContentTemplate>
        </asp:UpdatePanel>
        JS Button:
        <input id="Button5" type="button" value="Find My Location" onclick="getLocation()"/><input id="Button6" type="button" value="Clear Markers" onclick="clearMarkers()" /></form>
  • C#程式端,以Button3為例,這個按鈕的目的是取得B類的座標並繪製於地圖上
    protected void Button3_Click(object sender, EventArgs e)
    {
        Label1.Text = System.DateTime.Now.ToLongTimeString();
        Label1.Visible = true;

        string strJS = "";
        ArrayList alMarkers = GetMarkers("B");

        strJS = @"var sites = [" + String.Join(",", alMarkers.ToArray()) + "];setMarkers(sites);";
        ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alert", strJS, true);
    }
  • C#程式端,GetMarkers的目的是從資料庫取出對應的
protected ArrayList GetMarkers(string strType)
    {
        ArrayList alMarkers = new ArrayList();
        try
        {
            string conn = ConfigurationManager.ConnectionStrings["mydevConnectionString"].ConnectionString;
            using (SqlConnection connection = new SqlConnection(conn))
            {
                connection.Open();

                SqlCommand command = connection.CreateCommand();
                command.Connection = connection;

                if (strType == "ALL")
                {
                    command.CommandText = @"SELECT * FROM [MyDev].[dbo].[MyMap] with (nolock)";
                }
                else
                {
                    command.CommandText = @"SELECT * FROM [MyDev].[dbo].[MyMap] with (nolock) where Category=@Category";
                    command.Parameters.Add("@Category", SqlDbType.NVarChar, 20).Value = strType;
                }

                using (SqlDataReader dr = command.ExecuteReader())
                {
                    while (dr.Read())
                    {
                        alMarkers.Add("['" + dr["Project"].ToString() + "', " + dr["Latitude"].ToString() + "," + dr["Longtitude"].ToString() + ", 1, '" + dr["Info"].ToString() + "
" + dr["Addr"].ToString() + "']");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            lbErr.Text = ex.ToString();
            lbErr.Visible = true;
        }
        return alMarkers;
    }

  • Table的設計很簡單,主要就是 Latitude(緯度), Longtitude(經度),其他都是輔助描述的欄位
CREATE TABLE [dbo].[MyMap](
 [ID] [bigint] IDENTITY(1,1) NOT NULL,
 [Category] [nvarchar](20) NOT NULL,
 [Code] [nvarchar](20) NULL,
 [Info] [nvarchar](200) NULL,
 [Project] [nvarchar](50) NULL,
 [Addr] [nvarchar](100) NOT NULL,
 [Latitude] [float] NOT NULL,
 [Longtitude] [float] NOT NULL,
 [Coord] [geography] NULL
) ON [PRIMARY]


完成,結果如圖:
一進入網頁時,會直接定位目前座標,My Current Location 是我目前的座標,黃色是72公尺的精準度,其他的marker是點了B,帶入B類的座標,顯示在地圖上。

歡迎討論!

程式下載:
https://dl.dropbox.com/u/3330791/Sharecode/GoogleMapV3_ASPNET.rar

reference:
https://developers.google.com/maps/documentation/javascript/reference

2012年11月19日 星期一

[Toolkit] Get to Get coordinates in Images ? / 如何批次取得照片中的座標?

  • 目的:手邊有一些照片有座標資訊,現在需要取出座標內容進行後續的加值,除了一張一張照片打開看EXIF座標欄位以外,希望可以批次取得。
  • 使用工具:感謝這位日本網友 nissuk (https://github.com/nissuk),提供可用的powershell (https://gist.github.com/1360596),但是在中文環境下,會有問題,所以小弟有修改過,放在 http://dl.dropbox.com/u/3330791/get-exif.ps1 
  • 使用方式:
1 集合照片到同一個目錄,把 ps 直接放到到照片的目錄下

2 以Powershell執行 ps1,如果不只jpg,則請修改ps1的最後一行:
原本:dir "*.jpg" | get-exif | select name, latitude, longitude | export-csv
改為:dir "*.gif" | get-exif | select name, latitude, longitude | export-csv out.csv

2 執行結果:產生CSV檔案,這樣就完成了! 超級方便!


對這些有興趣的朋友,請看這個PowerShell Image module:
http://archive.msdn.microsoft.com/PSImage/

2012年10月19日 星期五

[Excel] 每個開發人員都需要知道的Excel公式


在這邊介紹幾個小弟經常用到的Excel公式,希望對大家使用Excel上有幫助。

1.字串處理
字串處理是用 Excel 給資訊人員最大的福利,尤其是需要批次處理時,不論是執行SQL、執行powershell 或整理報表,用Excel產生多筆的指令再去執行,真是省下很多作業的時間!

(1)合併Excel的欄位值:Excel的指令是=Concatenate(字串1, 字串2, 字串3...),譬如 =CONCATENATE("insert into tb  ([MyID],[MyDate1],[MyDate2],[MyCompany],[MyPosition],[Description])   values (",A2,",'",TEXT(C2,"yyyy/mm/dd"),"','",TEXT(D2,"yyyy/mm/dd"),"','",E2,"','",J2,"','",H2,"')")
的意思就是從A2~H2取欄位值出來,組合成 insert 指令。寫好第一行後,在Excel依次往下拉,就可以產生很多 insert 指令再貼到下Query的工具上,速度!

(2)取出固定文字的左邊或右邊:這種也常遇到,對於辦公室人員,Excel有些是要看的,但是不一定是結構性的資料,所以會有 "員工編號-XXX" 在同一個欄位出現,該如何處理呢 ? 譬如 1000-甲 要找出"-"左邊的ID,可以用 Find 這個公式找到"-"的位置,搭配Left,公式是 =LEFT(A1, FIND("-",A1)-1) ,長度要 "-1"是因為只要"100"。

如果要找右邊的,公式就寫成 =RIGHT(A1,LEN(A1)-FIND("-",A1))
公式的內容應該是不難懂,主要是組合多個公式起來,如果一開始不確定,也可以先個別計算,這樣就可以一步一步看結果。
(3)補0(或其他需要重複的字):主要是用REPT(重複字) 跟 LEN(值的文字長度)組合使用,譬如100,2000,30000都要補成 5碼的長度,公式是=CONCATENATE(REPT("0",5-LEN(B1)),B1),
分解步驟的話,公式的目的是
 - 重複0多次,要重複的次數:固定長度5 減掉100的長度(=3),所以是重複0共2次
 - 字串合併 00 與 100

2.資料取得對應值:在Excel 處理資料時,會遇到需要取得另一個表的值,也就是資料庫的join,可以使用: vlookup 這個公式,公式的格式是=Vlookup(來源的值,要查的範圍,要回傳的欄位位置,是否要完整比對)。
以下圖為例,公式是=VLOOKUP(A1,D:E,2,FALSE)  "我要找 A1 對應的值[第1個參數],去D與E構成的對應表去找[第2個參數],當A1對應到Excel Column D的值時,回傳第2行[第3個參數],比對時要完全正確才回傳[第4個參數]。
如果查不到,就會出現#N/A的訊息。

而#N/A是不是很刺眼呢,如果又要拿來串SQL指令時,#N/A會造成CONCATENATE失敗。
該如何避免呢?Excel有另一個公式叫做 ISError ,類似寫程式的try catch例外判斷,搭配IF,如: =IF(ISERROR(VLOOKUP(A1,D:E,2,FALSE)),"--",VLOOKUP(A1,D:E,2,FALSE))
意思是 "如果查到的結果是錯誤,就出現 --,如果不是錯誤,就出現查詢的結果",
看不到 #N/A,爽度也提高了

要注意的是
  • Vlookup第2個參數的對應表必須要排序過,要不然是查不到的。
  • 要拿來查詢的值與與對應表的值型態一樣才查的到,1(數字) 與 "1"(文字)是無法比對的上,用改格式的方式去處理會沒用,要用Text這個函數把數字改成文字,1才會變成"1"
  • 如果資料量很大,vlookup 搭配 iserror可能會花時間,不如copy結果出來成另一個Excel在交出去。
另外,
如果你的Excel很複雜,需要查多值,請google "excel array formula vlookup" 希望可以找到你要的答案。
Vlookup也可以自己查自己,因此可以做到類似 recursive 的效果,最適合在產生樹狀結構,如組織的結構,只要把key設為上層,就可以產生出 //公司//董事會//董事長//總經理//台灣分公司//資訊部 這樣的多層結構!

3.多IF的判斷:Excel 最單純的 IF是 =IF(條件,條件成立的值,條件不成立的值)。如果要做類似多層的IF判斷時,也就是要 Switch 時或 nested if ,Excel 也是用IF來達成,公式的範例

=IF(A1="A","1",
  IF(A1="B","2",
  IF(A1="C","3","N")
 ))
這樣Excel就會判斷
Switch(A1)
{
 case "A":"1"
 case "B":"2"
 case "C":"3"
 default: "N"
}
可以看圖也許比較清楚,公式內也可以按 ALT+Enter斷行作些簡單的程式排版,這樣就比較容易知道自己在寫些甚麼了!


Excel還有一些功能,像是清單整理出唯一值(如 SQL Distinct)、Column 轉 Row,都還滿常用的!
歡迎留言交流!

2012年5月12日 星期六

[Sharepoint 2010] 用Powershell建Sharepoint群組並指定權限 / Create Group Powershell and add permission


管理權限一直是各種系統的基礎重點,在Sharepoint跟AD的搭配上,都會以AGDLP去講該如何規劃設計。因此在管理 Sharepoint 群組的權限上,系統管理者(ㄞ  ㄊㄧ  ㄓㄨㄢ  ㄩㄢˊ)又要開熟悉Sharepoint Web/ Sharepoint Designer友善的畫面,以下要說明的是
1.在頂層網站建Group
2.把新建好的Group加到各下層的網站,並停止繼承
3.改下層網站各清單的權限


1.在頂層網站建Group,譬如有3個site
$web = Get-SPWeb "http://sps2010/"
$web.SiteGroups.Add("site1_A", $web.Site.Owner, $web.Site.Owner,"")
$web.SiteGroups.Add("site1_B", $web.Site.Owner, $web.Site.Owner,"")
$web.SiteGroups.Add("site1_C", $web.Site.Owner, $web.Site.Owner, "")
$web.SiteGroups.Add("site2_A", $web.Site.Owner, $web.Site.Owner,"")
$web.SiteGroups.Add("site2_B", $web.Site.Owner, $web.Site.Owner,"")
$web.SiteGroups.Add("site2_C", $web.Site.Owner, $web.Site.Owner, "")
$web.SiteGroups.Add("site3_A", $web.Site.Owner, $web.Site.Owner,"")
$web.SiteGroups.Add("site3_B", $web.Site.Owner, $web.Site.Owner,"")
$web.SiteGroups.Add("site3_C", $web.Site.Owner, $web.Site.Owner, "")
$web.Update()
$web.Dispose()

這一段沒什麼學問,如果需要一次建很多,其實可以用EXCEL去組合上面的字。建完Group後,如果需要先放群組的權限,建議用Sharepoint Designer,用Web去管理會在那邊等等等...

2.把新建好的Group加到各下層的網站,並停止繼承
###########################
#
# 函示:add group permission
#
###########################
function AddGroupToSite ($web, $groupName, $permLevel)
{
    $account = $web.SiteGroups[$groupName]
    $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
    $role = $web.RoleDefinitions[$permLevel]
    $assignment.RoleDefinitionBindings.Add($role);
    $web.RoleAssignments.Add($assignment)
}
#########

#Subsites待修改:看有哪些子網站要執行
$SubSites = @("site1","site2","site3"
)
for($i=0 ; $i -lt $SubSites.count ; $i++)
{
 $url = "http://sps2010/" + $SubSites[$i]
 $web = Get-SPWeb $url
 $web.BreakRoleInheritance($false)
 #Subsites待修改,看Group的名字
 $grp1 = $SubSites[$i]+"_A"
 $grp2 = $SubSites[$i]+"_B"
 $grp3 = $SubSites[$i]+"_C"
 AddGroupToSite -web $web -groupName $grp1 -permLevel "Read"
 AddGroupToSite -web $web -groupName $grp2 -permLevel "Read"
 AddGroupToSite -web $web -groupName $grp3 -permLevel "Read"
 $web.Dispose() 
 Write-Output $SubSites[$i] + " Completed!"
}

3.改下層網站各清單的權限
$web = Get-SPWeb "http://sps2010/"
#List Permission
#
#兩個清單要改:
#ListA: url是 /Site1/List/ListA
#ListB: url是 /Site1/SitePicLib
#如果有更多要改,就一直加在函示裡面
#
###########################
#
# 函示:Change List Permission
#
###########################
function ChangeListPermission ($strSiteName)
{
 $SubSites = $strSiteName
 $grp1 = $SubSites+"_A"
 $grp2 = $SubSites+"_B"
 $grp3 = $SubSites+"_C"
 $url = "http://sps2010/" + $SubSites
 $web = Get-SPWeb $url
 $admaccount = $web.EnsureUser("SHAREPOINT\system")
 #############################ListA#############################
 #$ListR = $web.Lists["ListA"]
 $strListURL = "/" + $SubSites + "/Lists/ListA"
 $ListR = $web.GetList($strListURL)
 $ListR.BreakRoleInheritance($false)
 $account = $web.SiteGroups[$grp2]
 $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
 $assignment.RoleDefinitionBindings.Add(($web.RoleDefinitions | Where-Object { $_.Type -eq "Contributor" }))
 $ListR.RoleAssignments.Add($assignment)
 $account = $web.SiteGroups[$grp4]
 $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
 $assignment.RoleDefinitionBindings.Add(($web.RoleDefinitions | Where-Object { $_.Type -eq "Contributor" }))
 $ListR.RoleAssignments.Add($assignment)
 $ListR.RoleAssignments.Remove($admaccount)
 #############################ListB#############################
 $strListURL = "/" + $SubSites + "/SitePicLib"
 $ListR = $web.GetList($strListURL)
 $ListR.BreakRoleInheritance($false)
 $account = $web.SiteGroups[$grp2]
 $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
 $assignment.RoleDefinitionBindings.Add(($web.RoleDefinitions | Where-Object { $_.Type -eq "Contributor" }))
 $ListR.RoleAssignments.Add($assignment)
 $account = $web.SiteGroups[$grp4]
 $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
 $assignment.RoleDefinitionBindings.Add(($web.RoleDefinitions | Where-Object { $_.Type -eq "Contributor" }))
 $ListR.RoleAssignments.Add($assignment)
 $account = $web.SiteGroups[$grp1]
 $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
 $assignment.RoleDefinitionBindings.Add($web.RoleDefinitions["Read"])
 $ListR.RoleAssignments.Add($assignment)
 $account = $web.SiteGroups[$grp3]
 $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
 $assignment.RoleDefinitionBindings.Add($web.RoleDefinitions["Read"])
 $ListR.RoleAssignments.Add($assignment)
 $ListR.RoleAssignments.Remove($admaccount)
 $web.Dispose()
}
###########################

#待修改
#實際呼叫函示
ChangeListPermission -strSiteName "site1"
ChangeListPermission -strSiteName "site2"
ChangeListPermission -strSiteName "site3"

權限這樣就差不多設定完成了,搭配Excel更快!
如果要對Sharepoint Group加AD Group,請看下一篇!


參考資料:
1.PowerShell to create SharePoint groups http://blog.pointbeyond.com/2011/06/03/powershell-to-create-sharepoint-groups/


#DontLikeSP

2012年3月1日 星期四

[Sharepoint 2010] 用Powershell 建網站 / Create web with Powershell

有鑑於 Sharepoint建網站的UI太友善了,讓要建多個網站的管理員會非常熟悉建站的動作跟設定,因此小弟到蒐集網路上各種建站的Powershell,東拼西湊成一個建多個站的Powershell:

1.如果有自訂的web template,則需要找出ID跟Name,可用:

 #待修改
 $url = "http://sps2010/"
 $site= new-Object Microsoft.SharePoint.SPSite($url )
 $loc= [System.Int32]::Parse(1033)
 $templates= $site.GetWebTemplates($loc)
   foreach ($child in $templates)
      {
               write-host $child.Name "  " $child.Title
      }
 $site.Dispose()





查詢出的結果會類似
{2F1B367A-5FF5-444E-B3BC-DBB73E1FEDXX}#SiteTemplateName    SiteTemplate_Title
只需要用到前面的,Title只是用來識別的

2.create it!
 以下的Powershell有包含以下步驟
 (1).建立一個新的網站
 (2).設定 "網站設定"的"其他語言",增加中文(1028)
 (3).設定 "網站設定"的"覆寫翻譯"
 (4).設定 "管理網站功能"的 "SharePoint Server Publishing"(為了master page)
 (5).設定 Master Page


#待修改

$SiteCollectionURL = "http://sps2010"

#待修改


$SiteCollectionTemplate = "
{2F1B367A-5FF5-444E-B3BC-DBB73E1FEDXX}#SiteTemplateName "

#預設語系英文

$SiteCollectionLanguage = 1033

#新站的URL

$SubSites = @("UrlA",

"UrlA",

"UrlA",

)

#新站的標題(Title)

$SubSiteNames =@("TitleA",

"TitleB",

"TitleC",

)

for($i=0 ; $i -lt $SubSites.count ; $i++)

{

 #(1).建立一個新的網站,根據指定的範本與語系,描述則預設為空白

 $SiteUrl = ""

 $SiteUrl = $SiteCollectionURL + "/"

 $SiteUrl = $SiteUrl += $SubSites[$i]

 $web=New-SPWeb $SiteUrl -Name $SubSiteNames[$i]  -UseParentTopNav -Language $SiteCollectionLanguage -Description " "
 #在我的環境,要再套用一次才會work, 不知道為什麼!
 $web.ApplyWebTemplate($SiteCollectionTemplate) 

 #(2).設定 "網站設定"的"其他語言",增加中文(1028)

 $web.IsMultilingual = $true

 $spReg = New-Object Microsoft.SharePoint.SPRegionalSettings $web

 #顯示安裝的language pack

 $spReg.InstalledLanguages

 $web.AddSupportedUICulture(1028)

 #(3).設定 "網站設定"的"覆寫翻譯"

 $web.OverwriteTranslationsOnChange = $true;

 #(4).設定 "管理網站功能"的 "SharePoint Server Publishing"(為了master page)

 Enable-SPFeature -identity "PublishingWeb" -URL $SiteUrl

 $web.Dispose()

 #Write-Output "完成: " += $SubSites[$i]


}

#

#(5).設定 Master Page

#因為需要web.update 所以分開執行

#

for($i=0 ; $i -lt $SubSites.count ; $i++)

{

 $SiteUrl = ""

 $SiteUrl = $SiteCollectionURL + "/"

 $SiteUrl = $SiteUrl += $SubSites[$i]

 $web = Get-SPWeb $SiteUrl

 $web.AllProperties["__InheritsCustomMasterUrl"] = "False";

 #待修改

 $web.CustomMasterUrl = "/_catalogs/masterpage/myv4.master"

 $web.AllProperties["__InheritsMasterUrl"] = "False";

  #待修改

 $web.MasterUrl = "/_catalogs/masterpage/myv4.master"

 $web.Update()

 $web.Dispose()

}


希望sharepoint後代多考慮管理員批次處理的功能,時間不是用來做重複的管理工作!

參考:



#DontLikeSP

2012年2月18日 星期六

[How to] 如何用C#使用Windows Fax / Fax with C# in Windows Fax Service Environment

[How to] Fax with C# in Windows Fax Service Environment
透過 Windows Fax Service,以程式方式發送傳真
  • 使用語言: C#
  • 加入參考 ( FXSRESM.dll ) 路徑在: C:\windows\system32\FXSRESM.dll
  • Code 如下:
    FaxServer faxServer = new FaxServer();
    //IP是Fax Server IP
    faxServer.Connect("192.168.1.1");
    FaxDocument aDoc = new FaxDocument();
    //要FAx的檔案
    aDoc.Body = "C:\\Temp\\1.docx";
    aDoc.ReceiptAddress = "stace@xxx";
    //收傳真的電話
    aDoc.Recipients.Add("88880000", "Recp");
    aDoc.ConnectedSubmit(faxServer);

  • 就這樣就可以發Fax出去, Stupid and simple! Good!
  • 其他傳真的封面/封底/Server傳送的狀態還需要再詳細看SDK與 COM Object的其他method! 基本上應該還要確認一下對方是否有傳成功,就類似人為動作一樣..

參考:

  • Using the Fax Service SDK http://msdn.microsoft.com/en-us/library/windows/desktop/ms693392(v=vs.85).aspx
  • Fax Service Extended COM Objects http://msdn.microsoft.com/en-us/library/windows/desktop/ms693456(v=vs.85).aspx